python连接linux服务器_Python (paramiko) 连接Linux服务器

参考资料

Paramiko

7d9183337c1eb5fc262c25413affa2af.png

简单说就是一款SSH2的连接工具,Python写的,作为一个测试用来干嘛尼,为了实现个需求,连上数据库服务器,备份/恢复SQL用,(测试前的数据备份-测试后的数据恢复,达到一个互不污染的数据环境, 思路提供者QQ: 1301559180)

安装

pip install paramiko

连接Linux

import paramiko

# SSH连接对象

ssh_client = paramiko.SSHClient()

# 自动接受服务器发过来的密钥

ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 用户名 + 密码连接

ssh_client.connect(hostname="192.168.60.222", port=22, username="root", password="123456")

# # 用户名 + 私钥连接; 私钥 文件路径

# private = paramiko.RSAKey.from_private_key_file(r'C:\Users\zy7y\.ssh\id_rsa')

# ssh_client.connect(hostname="192.168.60.222", port=22, username="root", pkey=private)

# 执行命令,得到结果 , 返回多个数据 第一个标准输入-用于交互式命令, 第二个标准输出-保存命令的正常执行结果, 第三个标准错误输出

stdin, stdout, stderr = ssh_client.exec_command("pwd")

# 返回类型字节 type(stdout.read())

# 转成字符串

print(stdout.read().decode())

# 关闭连接

ssh_client.close()

文件上传/下载

import paramiko

# 进行SSH连接

ssh_client = paramiko.Transport(("192.168.60.222", 22))

ssh_client.connect(username="root", password="123456")

# # 配置私人密钥文件位置

# private = paramiko.RSAKey.from_private_key_file('/Users/root/.ssh/id_rsa')

# # 连接SSH服务端,使用pkey指定私钥

# ssh_client.connect(username="root", pkey=private)

# 创建ftp客户端

ftp_client = paramiko.SFTPClient.from_transport(ssh_client)

# 上传文件到服务器,将当前目录下的test.sql 上传到服务器上

ftp_client.put(localpath="test.sql", remotepath="/root/test3/hello.sql")

# 下载文件到本地

ftp_client.get(localpath="test1.sql", remotepath="/root/test3/hello.sql")

# 关闭ssh连接

ssh_client.close()

3de6a1f49209dd10f3de47626c140b12.png

文件封装

#!/usr/bin/env python

# _*_ coding: utf-8 _*_

"""

@project: apiAutoTest

@file: ssh_demo.py

@author: zy7y

@time: 2021/1/18

@site: https://cnblogs.com/zy7y

@github: https://github.com/zy7y

@gitee: https://gitee.com/zy7y

@desc:

paramiko封装

"""

import paramiko

import os

class SSHTools:

def __init__(self, host: str, port: int = 22, username: str = "root",

password: str = None, private_key_file: str = None):

"""

SSH连接服务器的方案,密码(password)方式和私钥文件(private_key_file)方式只能选择一个

:param host: 主机地址 str

:param port: 主机端口 默认(int) 22

:param username: 登录时所用账号 默认(str) root

:param password: 账号所对应密码 (str) 默认 None

:param private_key_file: 私钥文件路径 (str) 默认None 与password 只可选择一个

"""

ssh_client = paramiko.SSHClient()

# 自动接受服务器发过来的密钥

ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

try:

if password is None:

# 用户名 + 私钥文件连接

ssh_client.connect(hostname=host, port=port, username=username,

pkey=paramiko.RSAKey.from_private_key_file(private_key_file))

else:

# 用户名 + 密码连接

ssh_client.connect(hostname=host, port=port, username=username, password=password)

print(f"SSH连接成功,address: {host}:{port}!")

self.ssh_client = ssh_client

except Exception as e:

print(f"SSH连接失败, 错误内容: {e}")

def execute_cmd(self, cmd: str):

"""

:param cmd: 服务器下对应的命令, 可以是list,或者str

"""

try:

if isinstance(cmd, list):

for c in cmd:

stdin, stdout, stderr = self.ssh_client.exec_command(c)

print(f"输入命令: {c} -> 输出结果: {stdout.read().decode()},\n异常信息: {stderr.read().decode()}")

else:

stdin, stdout, stderr = self.ssh_client.exec_command(cmd)

print(f"输入命令: {cmd} -> 输出结果: {stdout.read().decode()}\n异常信息: {stderr.read().decode()}")

except Exception as e:

print(f"错误如下, {e}")

def ssh_close(self):

"""关闭连接"""

self.ssh_client.close()

print("已关闭SSH连接...")

class SFTPTools:

def __init__(self, host: str, port: int = 22, username: str = "root", password: str = None, private_key_file: str = None):

# 进行SSH连接

ssh_client = paramiko.Transport((host, port))

self.host = host

if password is None:

ssh_client.connect(username="root", pkey=paramiko.RSAKey.from_private_key_file(private_key_file))

else:

ssh_client.connect(username=username, password=password)

self.ssh_client = ssh_client

# 创建ftp客户端

self.ftp_client = paramiko.SFTPClient.from_transport(ssh_client)

def files_action(self, post: bool, local_path: str = os.getcwd(), remote_path: str = "/root"):

"""

:param post: 动作 为 True 就是上传, False就是下载

:param local_path: 本地的文件路径, 默认当前脚本所在的工作目录

:param remote_path: 服务器上的文件路径,默认在/root目录下

"""

if post: # 上传文件

if remote_path[-1] != "/":

remote_path += "/"

self.ftp_client.put(localpath=local_path, remotepath=f"{remote_path}{os.path.split(local_path)[1]}")

print(f"文件上传成功: {local_path} -> {host}:{remote_path}{os.path.split(local_path)[1]}")

else: # 下载文件

if local_path[-1] != "\\":

local_path += "\\"

self.ftp_client.get(localpath=f"{local_path}{os.path.split(remote_path)[1]}", remotepath=remote_path)

print(f"文件下载成功: {host}:{remote_path}{os.path.split(local_path)[1]} -> {local_path}")

def ssh_close(self):

"""关闭连接"""

self.ssh_client.close()

print("已关闭SSH连接...")

if __name__ == '__main__':

# 自己的虚拟机哈

host = "192.168.60.222"

username = "root"

password = "123456"

ssh = SSHTools(host=host, username=username, password=password)

shell = "uname"

ssh.execute_cmd(shell)

ssh.ssh_close()

# SFTP

sftp = SFTPTools(host=host, username=username, password=password)

sftp.files_action(True, r"C:\Users\zy7y\Desktop\FastAPI.xmind", "/root")

sftp.files_action(0, remote_path="/root/FastAPI.xmind")

sftp.ssh_close()

另一种简洁点的

#!/usr/bin/env python

# _*_ coding: utf-8 _*_

"""

@project: apiAutoTest

@file: ssh_demo.py

@author: zy7y

@time: 2021/1/18

@site: https://cnblogs.com/zy7y

@github: https://github.com/zy7y

@gitee: https://gitee.com/zy7y

@desc:

paramiko封装

"""

# SSH + SFTP 参考链接 https://www.liujiangblog.com/blog/15/

class LinuxTools:

def __init__(self, host: str, port: int = 22, username: str = "root", password: str = None, private_key_file: str = None):

# 进行SSH连接

self.trans = paramiko.Transport((host, port))

self.host = host

if password is None:

self.trans.connect(username="root", pkey=paramiko.RSAKey.from_private_key_file(private_key_file))

else:

self.trans.connect(username=username, password=password)

# 将sshclient的对象的transport指定为以上的trans

self.ssh = paramiko.SSHClient()

self.ssh._transport = self.trans

# 创建SFTP客户端

self.ftp_client = paramiko.SFTPClient.from_transport(self.trans)

def execute_cmd(self, cmd: str):

"""

:param cmd: 服务器下对应的命令, 可以是list,或者str

"""

try:

if isinstance(cmd, list):

for c in cmd:

stdin, stdout, stderr = self.ssh.exec_command(c)

print(f"输入命令: {c} -> 输出结果: {stdout.read().decode()},\n异常信息: {stderr.read().decode()}")

else:

stdin, stdout, stderr = self.ssh.exec_command(cmd)

print(f"输入命令: {cmd} -> 输出结果: {stdout.read().decode()}\n异常信息: {stderr.read().decode()}")

except Exception as e:

print(f"错误如下, {e}")

def files_action(self, post: bool, local_path: str = os.getcwd(), remote_path: str = "/root"):

"""

:param post: 动作 为 True 就是上传, False就是下载

:param local_path: 本地的文件路径, 默认当前脚本所在的工作目录

:param remote_path: 服务器上的文件路径,默认在/root目录下

"""

if post: # 上传文件

if remote_path[-1] != "/":

remote_path += "/"

self.ftp_client.put(localpath=local_path, remotepath=f"{remote_path}{os.path.split(local_path)[1]}")

print(f"文件上传成功: {local_path} -> {self.host}:{remote_path}{os.path.split(local_path)[1]}")

else: # 下载文件

if local_path[-1] != "\\":

local_path += "\\"

self.ftp_client.get(localpath=f"{local_path}{os.path.split(remote_path)[1]}", remotepath=remote_path)

print(f"文件下载成功: {self.host}:{remote_path}{os.path.split(local_path)[1]} -> {local_path}")

def ssh_close(self):

"""关闭连接"""

self.trans.close()

print("已关闭SSH连接...")

if __name__ == '__main__':

# 自己的虚拟机哈

host = "192.168.60.222"

username = "root"

password = "123456"

ssh_sftp = LinuxTools(host=host, username=username, password=password)

ssh_sftp.execute_cmd("docker images")

ssh_sftp.files_action(True, r"C:\Users\zy7y\Desktop\FastAPI.xmind", "/root")

ssh_sftp.files_action(0, remote_path="/root/FastAPI.xmind")

ssh_sftp.ssh_close()

35f4125a51eff5aa83c90ff47461abe3.png

其他

找个时间把其和apiAutoTest集成一下吧~~~


版权声明:本文为weixin_39523280原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。