簡介
日常工作中經常需要通過SSH連接到多臺遠程服務器來完成各種任務,當需要操作的服務器眾多,且要執行的任務涉及命令繁多時,如果可以以自動化的方式模擬SSH連接及執行命令的繁瑣過程,對工作效率的提升是非常可觀的。
本文我就將帶大家學習在中使用非常強大的庫來對常用的遠程服務器連接管理操作進行自動化:
一、使用玩轉遠程服務器管理
基于強大的、等庫本地上傳文件到服務器,構建出一整套簡單易用的API,使得我們使用簡潔的語句就可以應付常見的各種遠程服務器操作,使用pip 完成安裝,本文演示對應版本為2.6。
1. 連接到遠程服務器并執行終端命令
要建立并保持對遠程服務器的連接,我們需要對.()進行實例化,其基礎參數有:
其他可用參數你可以前往
/en//api/.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()方法所執行的命令打印出的結果,可以通過屬性進行保存:
# hide=True抑制run()過程對執行結果的自動打印
output = c.run('df -h', hide=True).stdout
print(output)
獲悉了的基礎使用后本地上傳文件到服務器,接下來我們來學習一些進階內容:
2. 配置sudo命令密碼自動預填入
我們都知道,對于非root用戶,在執行某些權限較高的命令時需要添加sudo前綴,并在會話的初次執行時需要手動輸入當前用戶的密碼,而在中,有兩種方式可以實現這個步驟的自動化:
(1) 方式1:配合.
我們可以配合.來實現當命令行返回密碼輸入提示時,自動輸入并執行指定的命令:
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:利用.設置sudo密碼
除了上一種方式外,我們還可以使用.在創建連接時就一次性提前配置好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、之類的工具手動進行服務器與本地之間的文件相互傳輸,這些任務我們同樣可以在中自動化進行:
(1) 從本地上傳文件到服務器
使用put()方法可以將指定的本地文件上傳至服務器的指定位置,參數對應服務器目標保存位置:
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())
原文鏈接:/art//.htm?=&=