参考资料

https://www.liujiangblog.com/blog/15/

https://blog.csdn.net/leorx01/article/details/71141643

http://docs.paramiko.org/en/stable/api/client.html

https://www.bilibili.com/video/BV1cQ4y1P7dg?p=4

Paramiko

简单说就是一款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()) <class 'bytes'>
# 转成字符串
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()

文件封装

#!/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()

其他

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

Python (paramiko) 连接Linux服务器的更多相关文章

  1. Python ssh连接Linux服务器报Incompatible ssh peer (no acceptable kex algorithm) 解决方法

    python通过ssh连接linux服务器,部分服务器出现如下异常 03:50:48.725 FAIL ftp operation failed, Incompatible ssh peer (no ...

  2. python利用paramiko连接远程服务器执行命令

    python中的paramiko模块是用来实现ssh连接到远程服务器上的库,在进行连接的时候,可以用来执行命令,也可以用来上传文件. 1.得到一个连接的对象 在进行连接的时候,可以使用如下的代码: d ...

  3. ssh远程连接linux服务器并执行命令

    详细方法: SSHClient中的方法 参数和参数说明 connect(实现ssh连接和校验) hostname:目标主机地址 port:主机端口 username:校验的用户名 password:登 ...

  4. vscode远程连接linux服务器,可视化绘图

    vscode远程连接linux服务器 想要实现的功能和解决方案 实现的功能: windows下直接使用远程linux服务器的python环境和文件来编写和运行py文件, 实时的编写py文件,和可视化绘 ...

  5. ssh连接linux服务器只显示-bash-4.1#不显示路径解决方法

    ssh连接linux服务器只显示-bash-4.1#不显示路径时,我们只需要修改  ~/.bash_profile文件,如果不存在这个文件,那么新建一个,增加内容  export PS1='[\u@\ ...

  6. xshell连接linux服务器切换至oracle的sqlplus控制台时,无法使用回车键的解决方案!

    当使用xshell连接linux服务器后,切换至sqlplus控制台,当使用回车键时,出现^H的符号,貌似回车键不能用!解决方案: 1)$ stty erase ^H : 与退格键相关的设置是eras ...

  7. 【转】使用vnc连接linux服务器方便hadoop开发调试

    VNC(Virtual Network Computing)它能将完整的窗口界面通过网络,传输到另一台计算机的屏幕上. 类似的软件在Windows服务器中包含的"Terminal Serve ...

  8. mac通过自带的ssh连接Linux服务器并上传解压文件

    需求: 1:mac连接linux服务器 2:将mac上的文件上传到linux服务器指定位置 3:解压文件 mac上使用命令,推荐使用 iterm2 .当然,也可以使用mac自带的终端工具. 操作过程: ...

  9. Sublime 远程连接 Linux服务器

    Sublime是一款强大的编辑器,它的强大体现在它强大的插件. 要实现Sublime 远程连接 Linux服务器,需要使用插件SFTP. 一. 插件安装 用Package Control安装插件按下C ...

随机推荐

  1. 如何使用Nsight System?

    如何使用Nsight System?

  2. PyTorch中的MIT ADE20K数据集的语义分割

    PyTorch中的MIT ADE20K数据集的语义分割 代码地址:https://github.com/CSAILVision/semantic-segmentation-pytorch Semant ...

  3. python----日志模块loggin的使用,按日志级别分类写入文件

    1.日志的级别 日志一共分为5个等级,从低到高分别是: 级别 说明 DEBUG 输出详细的运行情况,主要用于调试. INFO 确认一切按预期运行,一般用于输出重要运行情况. WARNING 系统运行时 ...

  4. 编译原理-非确定有穷自动机(nondeterministic finite automata,NFA)

    是一个五元组,M=(S,∑,f,S0,F) S:有穷状态集 ∑:输入字母表(有穷) f:f(S,α)=S' 表示从一个状态S出发,识别了一个字α后,可以到达S'这个状态集合之间的某一个状态(可能的后继 ...

  5. NX二次开发-将3X3矩阵修正为正交且长度为单位长度的矩阵

    函数:UF_MTX3_ortho_normalize() 函数说明:将矩阵修正为正交且xyz长度为单位长度的矩阵.下图中输入的矩阵为三条线段的端点,经过修正后,生成一个坐标系. 1 #include ...

  6. 如何把excel中的行转为列?

    步骤:选择复制要转行的内容--->新建一张表格---->右键选择性粘贴---->转置----->成功把行转为列(具体操作看下图) 选择复制这些内容

  7. conn / as sysdba连接不上

    问题: SQL> conn / as sysdbaERROR:ORA-09817: Write to audit file failed.Linux-x86_64 Error: 28: No s ...

  8. SpringBoot项目创建流程--SpringMVC

    SpringBoot项目创建步骤 1. 创建SpringBoot工程 (1) File → New → Project → Spring Initilizr (2) Name:MySpringBoot ...

  9. windows下Docker Desktop安装管理

    检查要求 Windows 10 企业版.专业版或教育版 (必须windows10 1903版本以上)版本号 18362.1049+ 或 18363.1049+ ,次版本#大于.1049.最好是最新版( ...

  10. ExtJs4学习(四):Extjs 中id与itemId的区别

       为了方便表示或是指定一个组件的名称,我们通常会使用id或者itemId进行标识命名.(推荐尽量使用itemId,这样可以减少页面唯一标识而产生的冲突) id:   id是作为整个页面的Compo ...