Python使用Paramiko远程执行SSH命令与SFTP文件传输详解
本文详细介绍如何使用Python第三方库Paramiko实现远程服务器管理。通过SSHClient执行远程Shell命令,利用SFTPClient进行文件上传、下载及权限管理。涵盖连接认证、主机密钥策略配置及常用API用法,提供完整代码示例,帮助开发者高效自动化Linux运维任务。
楔子
在Python开发中,与Linux系统交互是常见需求,有时需要执行Shell命令。若仅在本地运行,可调用os.system或subprocess.Popen;但若需远程操作其他机器,则需借助第三方库paramiko。本文将演示如何利用Python远程操控其他服务器。
paramiko
网络通信遵循特定协议,如SSH。paramiko是一个基于Python的第三方库,实现了SSHv2协议(底层依赖cryptography库)。借助该库,Python可通过SSH协议连接远程服务器并执行操作,其功能与Xshell等终端工具类似。
注意:在Python代码中,我们直接通过SSH协议与远程服务器交互,而非调用系统的ssh命令。
使用前需先安装,执行pip install paramiko即可。
paramiko包含两大核心组件:SSHClient和SFTPClient。
SSHClient用于封装SSH会话,功能类似Linux下的ssh命令,主要用于执行远程命令。
SFTPClient用于封装SFTP客户端,功能类似Linux下的sftp命令,支持远程文件操作,如上传、下载及修改权限等。
接下来介绍它们的具体用法。
SSHClient的使用
首先创建客户端实例:client = paramiko.SSHClient(),随后该实例提供多种方法供调用。
connect:实现远程服务器的连接与认证
def connect(
self,
hostname,
port=SSH_PORT,
username=None,
password=None,
pkey=None,
key_filename=None,
timeout=None,
allow_agent=True,
look_for_keys=True,
compress=False,
sock=None,
gss_auth=False,
gss_kex=False,
gss_deleg_creds=True,
gss_host=None,
banner_timeout=None,
auth_timeout=None,
gss_trust_dns=True,
passphrase=None,
disabled_algorithms=None,
):
""""""
该函数参数众多,常用参数如下:
- hostname:目标主机地址,必选参数。
- port=SSH_PORT:指定端口,默认为22。
- username=None:登录用户名。
- password=None:用户密码。
- pkey=None:通过私钥进行身份验证。
- key_filename=None:私钥文件路径或列表。
- timeout=None:TCP连接超时时间(可选)。
- allow_agent=True:是否允许连接SSH代理,默认为True。
- look_for_keys=True:是否在~/.ssh中搜索私钥,默认为True。
- compress=False:是否启用压缩。
set_missing_host_key_policy:处理远程服务器缺少本地秘钥或HostKeys对象时的策略,支持三种模式:
- AutoAddPolicy:自动将主机名和秘钥添加到本地HostKeys,不依赖load_system_host_key配置。新建SSH连接时无需手动输入yes或no确认。
- WarningPolicy:记录未知主机秘钥的Python警告并接受连接。功能类似AutoAddPolicy,但会提示为新连接。
- RejectPolicy:自动拒绝未知主机名和秘钥,依赖load_system_host_key配置,此为默认选项。
因此,通常将策略设置为AutoAddPolicy,以避免本地配置麻烦。
exec_command:在远程执行具体的Linux命令。
open_sftp:在当前SSH会话基础上创建SFTP会话,返回SFTPClient对象,用于文件上传、下载等操作。后续将在SFTPClient部分详述。
下面演示具体用法:
import paramiko
# 实例化 SSHClient
client = paramiko.SSHClient()
# 自动添加策略, 保存服务器的主机名和密钥信息; 如果不添加, 那么不再本地 know_hosts 文件中的主机将无法连接
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接 SSH 服务端, 通过用户名和密码进行认证
# 该过程会创建一个 session, 它是 client 和 server 保持连接的对象
client.connect(hostname='47.94.174.89', port=22, username='root', password='xxxxxxx')
# 执行远程命令, 该方法会打开一个 paramiko.Channel 对象(类 socket, 一种安全的 SSH 传输通道)
# 会返回三个值, 分别是 stdin(标准输入)、stdout(标准输出)、stderr(错误输出)
stdin, stdout, stderr = client.exec_command("ls /")
# 打印执行结果, 显然我们要通过 stdout 来查看, 我们可以调用 stdout.read 获取执行的结果
# 但是返回的是字节, 所以需要先获取对应的编码, 然后再进行 decode
print(stdout.read().decode("utf-8"))
"""
bin
boot
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
"""
# 最后关闭 SSHClient 对象
client.close()
流程较为简单。若输入错误命令,stdout将无内容,因为错误信息会存入stderr中。
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname='47.94.174.89', port=22, username='root', password='xxxxxxx')
stdin, stdout, stderr = client.exec_command("xxxxx")
print(stderr.read().decode("utf-8"))
"""
bash: xxxxx: command not found
"""
client.close()
SFTPClient的使用
SFTPClient作为SFTP客户端对象,基于SSH传输协议的SFTP会话,可实现远程文件操作,如上传、下载、查看权限和状态等。
import paramiko
# 创建一个 Transport 对象, 使用时会同步创建一个 paramiko.Channel 对象
# 参数传递一个由 IP 和 PORT 组成的元组即可
transport = paramiko.Transport(("47.94.174.89", 22))
# 连接 ssh, 通过 username 和 password
transport.connect(username="root", password="xxxxxxx")
# 获取 SFTPClient 实例, 它便相当于 Linux 下的 sftp, 我们通过它可以进行文件的一些操作
sftp = paramiko.SFTPClient.from_transport(transport)
获取sftp对象后,支持以下操作:
- put(self, localpath, remotepath, callback=None, confirm=True):上传本地文件至服务器。callback为回调函数,上传成功后调用;confirm表示是否调用stat方法检查文件状态,返回ls -l结果。
- get(self, remotepath, localpath, callback=None):从服务器下载文件至本地。
- mkdir(self, path, mode=o777):在服务器创建目录,mode表示权限,默认为511(o777变量值为511)。
- rmdir(self, path):删除服务器目录。
- remove(self, path):删除服务器文件。
- rename(self, oldpath, newpath):重命名服务器目录或文件。
- stat(self, path):查看文件或目录状态。
- listdir(self, path='.'):列出服务器目录下文件。
- getcwd(self):查看当前工作区路径。
- chmod(self, path, mode):修改权限。
- chown(self, path, uid, gid):修改用户和组。
- chdir(self, path):切换工作区。
常用操作如上,下面进行演示。
# 1. 改变工作区
sftp.chdir("/usr/local/bin")
# 2. 查看工作区
print(sftp.getcwd()) # /usr/local/bin
sftp.chdir("/root")
print(sftp.getcwd()) # /root
"""
如果不调用 sftp.chdir(path) 的时候, 那么打印 sftp.getcwd() 时结果为 None
但我们知道登陆 Linux 时, 默认会在 /root 目录(对于 root 用户而言)
对于当前的 sftp 而言也确实如此, 只不过打印 sftp.getcwd() 的时候结果为 None 罢了
"""
# 3. 列出当前目录下的文件
print(sftp.listdir("/usr/local")) # ['lib', 'lib64', 'games', 'aegis', ...]
# 4. 查看文件或目录状态
print(sftp.stat("/root/.ssh/authorized_keys"))
"""
-rw------- 1 0 0 0 16 Dec 13:26 ?
"""
# 5. 改变权限
sftp.chmod("/root/.ssh/authorized_keys", 0o777)
print(sftp.stat("/root/.ssh/authorized_keys"))
"""
-rwxrwxrwx 1 0 0 0 16 Dec 13:26 ?
"""
# 6. 创建目录
print("dir" in sftp.listdir("/root")) # False
sftp.mkdir("/root/dir", mode=0o777)
print("dir" in sftp.listdir("/root")) # True
# 7. 删除目录
sftp.rmdir("/root/dir")
print("dir" in sftp.listdir("/root")) # False
# 8. 删除文件
sftp.remove("/root/1.py")
# 9. 下载文件
sftp.get("/root/makefile", r"makefile")
# 10. 上传文件
sftp.put("dockerfile", "/root/dockerfile")
# 最后关闭 sftp 和 transport
sftp.close()
transport.close()
如前所述,也可通过SSHClient的open_sftp方法创建SFTP客户端。
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname='47.94.174.89', port=22, username='root', password='xxxxxxx')
# 这种方式创建也是可以的
sftp = client.open_sftp()
以上为Python基于Paramiko库远程执行SSH命令及实现SFTP文件下载的详细内容,更多Python Paramiko库资料请关注本站相关文章。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









