(資料科學學習手札132)Python+Fabric實現遠端伺服器連線

費弗裡發表於2021-12-05

本文示例程式碼及檔案已上傳至我的Github倉庫https://github.com/CNFeffery/DataScienceStudyNotes

1 簡介

  日常工作中經常需要通過SSH連線到多臺遠端伺服器來完成各種任務,當需要操作的伺服器眾多,且要執行的任務涉及命令繁多時,如果可以以自動化的方式模擬SSH連線及執行命令的繁瑣過程,對工作效率的提升是非常可觀的。

  本文我就將帶大家學習在Python中使用非常強大的fabric庫來對常用的遠端伺服器連線管理操作進行自動化?:

(資料科學學習手札132)Python+Fabric實現遠端伺服器連線

2 使用fabric玩轉遠端伺服器管理

  fabric基於強大的paramikoinvoke等庫,構建出一整套簡單易用的API,使得我們使用簡潔的語句就可以應付常見的各種遠端伺服器操作,使用pip install fabric完成安裝,本文演示對應版本為2.6

2.1 連線到遠端伺服器並執行終端命令

  要建立並保持對遠端伺服器的連線,我們需要對fabric.Connection()進行例項化,其基礎引數有:

  • host: str型,格式如'使用者名稱@host:埠',其中':埠'部分可以省略,預設埠為22

  • connect_kwargs: dict型,用於傳入其他連線所需引數,常用的有:

    • password: str型,當以密碼方式連線時,用於傳入與host引數對應的密碼
    • pkey: str型,當以私鑰方式連線時,用於設定對應金鑰
    • timeout: float型,用於設定TCP連線的超時時長(單位:秒)

    其他可用引數你可以前往https://docs.paramiko.org/en/latest/api/client.html#paramiko.client.SSHClient.connectParameters瞭解更多

  • 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(
                   password=password
               ))

# 利用run方法直接執行傳入的命令
c.run('pwd');
(資料科學學習手札132)Python+Fabric實現遠端伺服器連線

  可以看到,非常簡單就完成了連線伺服器及執行指定命令的過程,且run()方法所執行的命令列印出的結果,可以通過stdout屬性進行儲存:

# hide=True抑制run()過程對執行結果的自動列印
output = c.run('df -h', hide=True).stdout
print(output)
(資料科學學習手札132)Python+Fabric實現遠端伺服器連線

  獲悉了fabric的基礎使用後,接下來我們來學習一些進階內容:

2.2 配置sudo命令密碼自動預填入

  我們都知道,對於非root使用者,在執行某些許可權較高的命令時需要新增sudo字首,並在會話的初次執行時需要手動輸入當前使用者的密碼,而在fabric中,有兩種方式可以實現這個步驟的自動化:

2.2.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]);
(資料科學學習手札132)Python+Fabric實現遠端伺服器連線

2.2.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},
               config=config)

c.sudo('pwd');
(資料科學學習手札132)Python+Fabric實現遠端伺服器連線

2.3 遠端檔案傳輸

  很多朋友都知道可以使用pscpxshell之類的工具手動進行伺服器與本地之間的檔案相互傳輸,這些任務我們同樣可以在fabric中自動化進行:

2.3.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');
(資料科學學習手札132)Python+Fabric實現遠端伺服器連線

2.3.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())
(資料科學學習手札132)Python+Fabric實現遠端伺服器連線

  以上就是本文的全部內容,歡迎在評論區與我進行討論~

相關文章