paramiko 的核心组件

paramiko 包含两个核心组件,一个为 SSHClient 类,另一个为 SFTPClient 类,下面详细介绍。

SSHClient类

SSHClient 类是 SSH 服务会话的高级表示,该类封装了传输(transport)、通道(channel)及 SFTPClient 的校验、建立的方法,通常用于执行远程命令,下面是一个简单的例子:

client = SSHClient()
client.load_system_host_keys()
client.connect('ssh.example.com')
stdin, stdout, stderr = client.exec_command('ls -l')

下面介绍 SSHClient 常用的几个方法。

connect方法

connect 方法实现了远程 SSH 连接并校验。

方法定义:

connect(self, hostname, port=22, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False)

参数说明:

  • hostname(str 类型),连接的目标主机地址;

  • port(int 类型),连接目标主机的端口,默认为22;

  • username(str 类型),校验的用户名(默认为当前的本地用户名);

  • password(str 类型),密码用于身份校验或解锁私钥;

  • pkey(PKey 类型),私钥方式用于身份验证;

  • key_filename(str or list(str) 类型),一个文件名或文件名的列表,用于私钥的身份验证;

  • timeout(float 类型),一个可选的超时时间(以秒为单位)的 TCP 连接;

  • allow_agent(bool 类型),设置为 False 时用于禁用连接到 SSH 代理;

  • look_for_keys(bool 类型),设置为 False 时用来禁用在 ~/.ssh 中搜索私钥文件;

  • compress(bool 类型),设置为 True 时打开压缩。

exec_command方法

远程命令执行方法,该命令的输入与输出流为标准输入(stdin)、输出(stdout)、错误(stderr)的 Python 文件对象,方法定义:

exec_command(self, command, bufsize=-1)

参数说明:

  • command(str 类型),执行的命令串;

  • bufsize(int 类型),文件缓冲区大小,默认为 -1(不限制)。

load_system_host_keys方法

加载本地公钥校验文件,默认为 ~/.ssh/known_hosts,非默认路径需要手工指定,方法定义:

load_system_host_keys(self, filename=None)

参数说明:

  • filename(str 类型),指定远程主机公钥记录文件。

set_missing_host_key_policy方法

设置连接的远程主机没有本地主机密钥或 HostKeys 对象时的策略,目前支持三种,分别是 AutoAddPolicy、RejectPolicy(默认)、WarningPolicy,仅限用于 SSHClient 类,分别代表的含义如下:

  • AutoAddPolicy,自动添加主机名及主机密钥到本地 HostKeys 对象,并将其保存,不依赖 load_system_host_keys() 的配置,即使 ~/.ssh/known_hosts 不存在也不产生影响;

  • RejectPolicy,自动拒绝未知的主机名和密钥,依赖 load_system_host_keys() 的配置;

  • WarningPolicy,用于记录一个未知的主机密钥的 Python 警告,并接受它,功能上与 AutoAddPolicy 相似,但未知主机会有告警。

使用方法如下:

ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

SFTPClient类

SFTPClient 作为一个 SFTP 客户端对象,根据 SSH 传输协议的 sftp 会话,实现远程文件操作,比如文件上传、下载、权限、状态等操作,下面介绍 SFTPClient 类的常用方法。

from_transport方法

创建一个已连通的 SFTP 客户端通道,方法定义:

from_transport(cls, t)

参数说明:

  • t(Transport),一个已通过验证的传输对象。

例子说明:

t = paramiko.Transport(("192.168.1.22",22))
t.connect(username="root", password="KJSdj348g")
sftp =paramiko.SFTPClient.from_transport(t)

put方法

上传本地文件到远程 SFTP 服务端,方法定义:

put(self, localpath, remotepath, callback=None, confirm=True)

参数说明:

  • localpath(str 类型),需上传的本地文件(源);

  • remotepath(str 类型),远程路径(目标);

  • callback(function(int, int)),获取已接收的字节数及总传输字节数,以便回调函数调用,默认为 None;

  • confirm(bool 类型),文件上传完毕后是否调用 stat() 方法,以便确认文件的大小。

例子说明:

localpath='/home/access.log'
remotepath='/data/logs/access.log'
sftp.put(localpath,remotepath)

get方法

从远程 SFTP 服务端下载文件到本地,方法定义:

get(self, remotepath, localpath, callback=None)

参数说明:

  • remotepath(str 类型),需下载的远程文件(源);

  • localpath(str 类型),本地路径(目标);

  • callback(function(int, int)),获取已接收的字节数及总传输字节数,以便回调函数调用,默认为 None。

例子说明:

remotepath='/data/logs/access.log'
localpath='/home/access.log'
sftp.get(remotepath, localpath)

其他方法

SFTPClient 类其他常用方法说明:

  • Mkdir,在 SFTP 服务器端创建目录,如 sftp.mkdir("/home/userdir",0755)。

  • remove,删除 SFTP 服务器端指定目录,如 sftp.remove("/home/userdir")。

  • rename,重命名 SFTP 服务器端文件或目录,如 sftp.rename("/home/test.sh","/home/testfile.sh")。

  • stat,获取远程 SFTP 服务器端指定文件信息,如 sftp.stat("/home/testfile.sh")。

  • listdir,获取远程 SFTP 服务器端指定目录列表,以 Python 的列表(List)形式返回,如 sftp.listdir("/home")。

SFTPClient类应用示例

下面为 SFTPClient 类的一个完整示例,实现了文件上传、下载、创建与删除目录等,需要注意的是,put 和 get 方法需要指定文件名,不能省略。详细源码如下:

#!/usr/bin/env python
import paramiko

username = "root"
password = "KJsd8t34d"
hostname = "192.168.1.21"
port = 22

try:
    t = paramiko.Transport((hostname, port))
    t.connect(username=username, password=password)
    sftp = paramiko.SFTPClient.from_transport(t)
    sftp.put("/home/user/info.db", "/data/user/info.db")  # 上传文件
    sftp.get("/data/user/info_1.db", "/home/user/info_1.db")  # 下载文件
    sftp.mkdir("/home/userdir", 0755)  # 创建目录
    sftp.rmdir("/home/userdir")  # 删除目录
    sftp.rename("/home/test.sh", "/home/testfile.sh")  # 文件重命名
    print(sftp.stat("/home/testfile.sh"))  # 打印文件信息
    print(sftp.listdir("/home"))  # 打印目录列表
    t.close();
except Exception as e:
    print(str(e))