介紹
這篇文章簡單地介紹了python的paramiko模塊的用法,paramiko實現了SSH協議,能夠方便地與遠程計算機交互。簡單的說,就是你在terminal下執行的如下語句,現在可以通過python的paramiko實現了。
# 執行shell語句
ssh -i ~/.ssh/id_rsa -p 1098 [email protected] -e 'ls -al'
# 拷貝數據到遠程計算機
scp -i ~/.ssh/id_rsa -P 1098 -r data [email protected]:~/data
這裏不討論shell與python實現的優缺點,如果你沒有需求,也不會看到這篇博客了。我個人使用paramiko是爲了使用python的多線程,併發地對多臺遠程計算機執行相同的操作。
安裝
安裝非常簡單,直接使用pip安裝即可:
pip instal paramiko
建立SSH連接
使用密碼連接:
import paramiko
ssh = paramiko.SSHClient()
#這行代碼的作用是允許連接不在know_hosts文件中的主機。
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("IP", port, "username", "password")
使用私鑰連接:
ssh = paramiko.SSHClient()
ssh.connect('10.120.48.109', port, '用戶名', key_filename='私鑰')
連接以後可以執行shell命令:
In [8]: ssh.exec_command('ls')
Out[8]:
(<paramiko.ChannelFile from <paramiko.Channel 1 (open) window=2097152 -> <paramiko.Transport at 0x377c690L (cipher aes128-ctr, 128 bits) (active; 2 open channel(s))>>>,<paramiko.ChannelFile from <paramiko.Channel 1 (open) window=2097152 -> <paramiko.Transport at 0x377c690L (cipher aes128-ctr, 128 bits) (active; 2 open channel(s))>>>,<paramiko.ChannelFile from <paramiko.Channel 1 (open) window=2097152 -> <paramiko.Transport at 0x377c690L (cipher aes128-ctr, 128 bits) (active; 2 open channel(s))>>>)
執行shell命令以後,並不會立即打印命令的執行結果,而是返回幾個Channel, 只能像下面這樣獲取輸出:
In [9]: stdin, stdout, stderr = ssh.exec_command('ls')
In [10]: print stdout.readlines()
['AgentBackkup_2015-06-11\n', 'AgentBackup\n', 'log\n', 'mysql.sh\n', 'rdsAgent\n']
注意: 命令執行出錯並不會拋出異常,所以,對於命令出錯需要根據自己的需求進行相應的處理:
In [54]: stdin, stdout, stderr = ssh.exec_command('cat file_not_found')
In [55]: print stdout.readlines()
[]
In [56]: print stderr.readlines()
[u'cat: file_not_found: No such file or directory\n']
In [57]: stdin, stdout, stderr = ssh.exec_command('ls')
In [58]: print stderr.readlines()
[]
API文檔: https://paramiko-docs.readthedocs.org/en/1.15/api/client.html
SCP vs SFTP
通過paramiko還可以傳輸文件,這是我寫這篇博客的主要原因。搜了很多博客,都沒有說明白如何通過paramiko在計算機之間傳輸文件,通過閱讀官方文檔,發現有如下兩種方式:
sftp = paramiko.SFTPClient.from_transport(ssh.get_transport())
sftp = ssh.open_sftp()
即新建一個SFTPClient對象,該對象複用之前的SSH連接,因此,我們使用sftp傳輸文件時,不需要再次進行用戶認證。
文件上傳
In [59]: sftp.put('memory.py', 'memory.py')
Out[59]: <SFTPAttributes: [ size=288 uid=1000 gid=1000 mode=0100644 atime=1435391914 mtime=1435391914 ]>
文件下載
In [60]: sftp.get('memory.py', 'backup.py')
執行命令
paramiko並沒有提供一個叫做scp的子模塊,如果我們希望在計算機之間傳輸數據,可以通過sftp(sftp實現了scp所有的功能,也就沒有必再實現一個scp)傳輸文件,還可以通過sftp執行命令,如下所示:
In [44]: sftp.listdir()
In [45]: sftp.rename('AgentBackkup_2015-06-10', 'AgentBackkup_2015-06-11')
In [46]: sftp.listdir()
sftp提供了很多命令,具體內容可以參考官方文檔 。