简介
日常工作中经常需要通过SSH连接到多台远程服务器来完成各种任务,远程当需要操作的连接服务器众多,且要执行的服务任务涉及命令繁多时,如果可以以自动化的器用方式模拟SSH连接及执行命令的繁琐过程,对工作效率的远程提升是非常可观的。
本文我就将带大家学习在Python中使用非常强大的连接fabric库来对常用的远程服务器连接管理操作进行自动化:

一、使用fabric玩转远程服务器管理
fabric基于强大的服务paramiko、invoke等库,器用构建出一整套简单易用的远程API,使得我们使用简洁的连接语句就可以应付常见的各种远程服务器操作,使用pip install fabric完成安装,服务本文演示对应版本为2.6。器用
1. 连接到远程服务器并执行终端命令
要建立并保持对远程服务器的远程连接,亿华云我们需要对fabric.Connection()进行实例化,连接其基础参数有:
「host:」 str型,服务格式如用户名@host:端口,其中:端口部分可以省略,默认端口为22 「connect_kwargs:」 dict型,用于传入其他连接所需参数,常用的有: 其他可用参数你可以前往
https://docs.paramiko.org/en/latest/api/client.html#paramiko.client.SSHClient.connect的Parameters了解更多。
「password:」 str型,当以密码方式连接时,用于传入与host参数对应的密码 「pkey:」 str型,当以私钥方式连接时,用于设置对应密钥 「timeout:」 float型,用于设置TCP连接的超时时长(单位:秒) 「config:」 fabric.Config型,用于设置更多复杂功能参数,详见https://docs.fabfile.org/en/2.6/api/config.html 先来看一个最基础的例子:
from fabric import Connection # 建议将ssh连接所需参数变量化 user = 用户名 host = host地址 password = 密码 # 利用fabric.Connection快捷创建连接 c = Connection(host=f{ user}@{ host}, connect_kwargs=dict( passwordpassword=password )) # 利用run方法直接执行传入的命令 c.run(pwd); 
可以看到,非常简单就完成了连接服务器及执行指定命令的过程,且run()方法所执行的命令打印出的结果,服务器托管可以通过stdout属性进行保存:
# hide=True抑制run()过程对执行结果的自动打印 output = c.run(df -h, hide=True).stdout print(output) 
获悉了fabric的基础使用后,接下来我们来学习一些进阶内容:
2. 配置sudo命令密码自动预填入
我们都知道,对于非root用户,在执行某些权限较高的命令时需要添加sudo前缀,并在会话的初次执行时需要手动输入当前用户的密码,而在fabric中,有两种方式可以实现这个步骤的自动化:
(1) 方式1:配合invoke.Responder
我们可以配合invoke.Responder来实现当命令行返回密码输入提示时,自动输入并执行指定的命令:
from invoke import Responder # 配置命令行内容监听规则 sudopass = Responder( pattern=f\[sudo\] password for { user}:, response=password+\n ) # 注意需要设置pty=True c.run(sudo pwd, pty=True, watchers=[sudopass]); 
(2) 方式2:利用fabric.Config设置sudo密码
除了上一种方式外,我们还可以使用fabric.Config在创建连接时就一次性提前配置好sudo密码,之后需要执行sudo命令时用sudo()方法代替run()方法即可:
from fabric import Config # 预先配置sudo密码 config = Config(overrides={ sudo: { password: password } }) c = Connection(host=f{ user}@{ host}, connect_kwargs={ password: password}, configconfig=config) c.sudo(pwd); 
3. 远程文件传输
很多朋友都知道可以使用pscp、xshell之类的工具手动进行服务器与本地之间的文件相互传输,这些任务我们同样可以在fabric中自动化进行:
(1) 从本地上传文件到服务器
使用put()方法可以将指定的本地文件上传至服务器的指定位置,remote参数对应服务器目标保存位置:
c = Connection(host=f{ user}@{ host}, connect_kwargs={ password: password}) # 创建示例文件 with open(file_transfer.txt, w) as d: d.write(1) # 利用put方法上传至服务器 c.put(file_transfer.txt, remote=/home/feffery/) # 打印已上传文件内容 c.run(cat /home/feffery/file_transfer.txt); 
(2) 从服务器下载指定文件到本地
相反的,当我们需要从服务器取回指定文件到本地时,源码下载就可以使用get()方法:
c = Connection(host=f{ user}@{ host}, connect_kwargs={ password: password}) # 向文件末尾追加行 c.run(echo "\n2" >> file_transfer.txt) c.get(/home/feffery/file_transfer.txt) print(open(file_transfer.txt).read()) 