由于工作中经常用到这两个库,不过基本上用的fabric来实现环境部署、预检、数据上传下发等操作。因此,本文重点介绍Fabric的使用(fabric2版本)。
paramiko
paramiko是使用SSHv2协议的三方库,提供了客户端和服务端的功能。
Welcome to Paramiko’s documentation! — Paramiko documentation
安装
| |
paramiko中的几个重要组件:
SSHClient:ssh服务器会话的高级封装,封装了Transport,Channel, andSFTPClientSFTPClient:基于一个已连通的Transport打开一个sftp会话,可实现对文件的操作(上传下载等)
Channel:一种ssh传输的安全通道,类似socketTransport:一种协商加密的会话,会创建tunnels通道流,称为channels。多个channels可以在单个会话中多路复用
SSHClient
连接
- 通过密钥连接,有两种方式:
- 实例化
SSHClient - 创建一个
Transport加密通道
- 实例化
- 通过密码连接,有两种方式:
- 实例化
SSHClient - 创建一个
Transport加密通道
- 实例化
| |
执行SSH命令
通过exec_command()方法打开一个channel在服务器上执行命令,相当于我们使用ssh客户端工具执行。
若要执行多个命令可以通过 &&连接,或者for循环调用exec_command(),这将会打开多个channel。
| |
执行完成后会一次性返回stdout和stderr,同时可以通过stdout.channel.recv_exit_status()获取执行结果,该方法是一个阻塞方法,如果想实时获取日志输出可以封装一下,代码如下:
| |
关闭连接
ssh_client.close()transport.close()
SFTPClient
创建SFTP客户端通道
| |
常用操作
listdir(path):遍历远程路径下的文件目录(只能遍历一级目录和文件)listdir_attr(path):遍历远程路径下的文件目录,并且可以获取每个文件的详细属性remove(path):删除文件rmdir(path):删除目录mkdir(path):创建目录stat(path):获取文件属性信息(若为软链接文件,获取的是指向的源文件)lstat(path):获取文件属性信息(若为软链接文件,获取的是自身文件)get(remotepath, localpath):下载put(localpath, remotepath):上传
检查远程文件是否存在
| |
判断远程路径是否为目录
| |
上传
注意:远程目录必须存在,否则会报错
| |
下载
注意:本地目录必须存在,否则会报错
| |
关闭
sftp.close()
封装
| |
fabric
fabric是基于paramiko的进一步封装,使用起来更加方便。fabric共有三个版本:fabric1、fabric2、fabric3,其中fabric3是非官方版本,所以不推荐使用,建议使用fabric2版本。
官方文档:https://www.fabfile.org/
安装
pip install fabric或者pip install fabric2,都是安装最新的官方版本。
使用
连接
| |
关于run()方法的参数说明:
| 参数 | 解释 |
|---|---|
| hide=True | 服务器的输出信息不会在控制台打印 |
| warn=True | 忽略异常信息(即exit code不等于0的命令),会将异常信息输出到stderr,若设置False则会报SystemExit异常,之前在测试环境就是因为没有处理这个SystemExit异常(SystemExit和Exception是同级关系),导致整个进程崩溃 |
| pty=True | 交互式伪终端时使用,其他不建议使用 |
| watchers | 监听Responder列表,自动响应 |
| out_stream | 文件对象,可以记录命令输出信息(fabric1版本的参数好像是stdout) |
| err_stream | 文件对象,可以记录命令错误输出信息 |
ret = run()方法返回值:
| |
执行交互式命令
如果需要用户主动输入命令,可以使用Responder,第一个参数为需要匹配的字符串,第二个参数为响应的内容。由于交互式终端原因,此处需要设置pty=True,否则运行会提示:no tty present and no askpass program specified,若提示xx user is not in the sudoers file. This incident will be reported,需要通过登录root用户,修改sudoers文件。
特别注意:模式匹配字符串要转义,否则会匹配不到,进而一直阻塞无响应(凡是需要用户介入的操作,都会一直卡在那里直到给出响应);response内容必须以\n紧接结尾,相当于输入完成后执行回车操作。
| |
with用法:
| |
执行本地命令
| |
操作多台机器
| |
| |
上传文件
fabric只能上传单个文件,如果想上传多个文件,有两种方案:本地打包之后上传,然后在远程服务器执行解压操作,或者通过遍历文件夹循环调用get上传,本地目录遍历用到了pathlib2.Path中的rglob方法。注意:远程路径如果不存在会报错。
| |
下载文件
fabric下载文件的方法和paramiko有略微细节差异,fabric下载文件时若本地路径不存在会自动创建,并且本地路径如果没提供文件名,会以远程文件名作为默认值,但前提是本地路径以/结尾,如果没有/,将以路径最后一部分作为文件名。
| |
fab命令
fab –help查看具体命令含义,这里列举的是fabric2的常用fab命令参数,和fabric1版本有很大不同。具体请参考Upgrading from 1.x — Fabric documentation (fabfile.org)
| 参数 | 解释 |
|---|---|
| -l | 列举任务列表(被@task装饰的函数才能被识别) |
| -c | 从指定的任务模块名加载(默认为fabfile.py) |
| -r | 从指定的根目录路径查找任务模块 |
| -f | 指定配置文件路径 |
| -H | 指定目标主机,多个主机逗号隔开 |
| -V | 显示Fabric、Paramiko、Invoke版本 |
| -w | 和warn=True效果一样,出现异常不会结束 |
示例
| |
其中被@task装饰的函数必须有一个参数,否则会报:TypeError: Tasks must have an initial Context argument!。
假如入口文件不是fabfile.py且不指定的话,会报Can't find any collection named 'fabfile'!,fabric2中通过-c来指定加载的任务列表,官方API文档也说明了:–collection后面的参数是模块名而不是具体文件名。
比如上述的task函数存在于服务器/home/yuqiuwen/PythonProjects/zhongxin/fab.py路径下。
| |
除此之外,还可以通过fab -l -F指定显示格式:
| |
封装
| |