paramiko模塊提供了ssh及sft進行遠程登陸服務器執行命令和上傳下載文件的功能。這是一個第三方的軟件包,使用以前須要安裝。ios
1. 基於用戶名和密碼的sshclient方式登陸shell
1 #建立一個sshclient對象 2 ssh = paramiko.SSHClient() 3 #容許將信任的主機自動加入到host_allow列表,此方法必須放在connect方法以前 4 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 5 # 執行命令 6 stdin, stdout, stderr = ssh.exec_command('ps -ef') 7 # 結果放到stdout中,若是有錯誤將放到stderr中 8 print(stdout.read().decode()) 9 # 關閉鏈接 10 ssh.close()
2. 基於用戶名和密碼的transport方式登陸服務器
第一種方法是傳統的鏈接服務器、執行命令、關閉的一個操做,有時候須要登錄服務器執行多個操做,好比執行命令、上傳/下載文件,方法一沒法實現,能夠經過以下方式來操做session
1 #實例化一個transport對象 2 trans = paramiko.Transport(('192.168.2.129',22)) 3 #創建鏈接 4 trans.connect(username = 'zhangce',password='123') 5 6 #將sshclient對象的transport指定爲以上的trans 7 ssh = paramiko.SSHClient() 8 ssh._transport = trans 9 10 # 執行命令,和傳統方法同樣 11 stdin, stdout, stderr = ssh.exec_command('df -hl') 12 print(stdout.read().decode()) 13 14 # 關閉鏈接 15 trans.close()
3. 基於公鑰祕鑰的SSHClient方式登陸ssh
1 # 指定本地的RSA私鑰文件,若是創建密鑰對時設置的有密碼,password爲設定的密碼,如無不用指定password參數 2 pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345') 3 # 創建鏈接 4 ssh = paramiko.SSHClient() 5 ssh.connect(hostname='192.168.2.129', 6 port=22, 7 username='super', 8 pkey=pkey) 9 # 執行命令 10 stdin, stdout, stderr = ssh.exec_command('df -hl') 11 # 結果放到stdout中,若是有錯誤將放到stderr中 12 print(stdout.read().decode()) 13 # 關閉鏈接 14 ssh.close()
以上須要確保被訪問的服務器對應用戶.ssh目錄下有authorized_keys文件,也就是將服務器上生成的公鑰文件保存爲authorized_keys。並將私鑰文件做爲paramiko的登錄密鑰 socket
4. 基於密鑰的 Transport 方式登陸工具
1 # 指定本地的RSA私鑰文件,若是創建密鑰對時設置的有密碼,password爲設定的密碼,如無不用指定password參數 2 pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345') 3 # 創建鏈接 4 trans = paramiko.Transport(('192.168.2.129', 22)) 5 trans.connect(username='super', pkey=pkey) 6 7 # 將sshclient的對象的transport指定爲以上的trans 8 ssh = paramiko.SSHClient() 9 ssh._transport = trans 10 11 # 執行命令,和傳統方法同樣 12 stdin, stdout, stderr = ssh.exec_command('df -hl') 13 print(stdout.read().decode()) 14 15 # 關閉鏈接 16 trans.close()
5. 傳文件 SFTPspa
1 # 實例化一個trans對象# 實例化一個transport對象 2 trans = paramiko.Transport(('192.168.2.129', 22)) 3 # 創建鏈接 4 trans.connect(username='super', password='super') 5 6 # 實例化一個 sftp對象,指定鏈接的通道 7 sftp = paramiko.SFTPClient.from_transport(trans) 8 # 發送文件 9 sftp.put(localpath='/tmp/11.txt', remotepath='/tmp/22.txt') 10 # 下載文件 11 # sftp.get(remotepath, localpath) 12 trans.close()
6. 實現輸入命令立馬返回結果的功能
以上操做都是基本的鏈接,若是咱們想實現一個相似xshell工具的功能,登陸之後能夠輸入命令回車後就返回結果:.net
1 import paramiko 2 import os 3 import select 4 import sys 5 6 # 創建一個socket 7 trans = paramiko.Transport(('192.168.2.129', 22)) 8 # 啓動一個客戶端 9 trans.start_client() 10 11 # 若是使用rsa密鑰登陸的話 12 ''' 13 default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') 14 prikey = paramiko.RSAKey.from_private_key_file(default_key_file) 15 trans.auth_publickey(username='super', key=prikey) 16 ''' 17 # 若是使用用戶名和密碼登陸 18 trans.auth_password(username='super', password='super') 19 # 打開一個通道 20 channel = trans.open_session() 21 # 獲取終端 22 channel.get_pty() 23 # 激活終端,這樣就能夠登陸到終端了,就和咱們用相似於xshell登陸系統同樣 24 channel.invoke_shell() 25 # 下面就能夠執行你全部的操做,用select實現 26 # 對輸入終端sys.stdin和 通道進行監控, 27 # 當用戶在終端輸入命令後,將命令交給channel通道,這個時候sys.stdin就發生變化,select就能夠感知 28 # channel的發送命令、獲取結果過程其實就是一個socket的發送和接受信息的過程 29 while True: 30 readlist, writelist, errlist = select.select([channel, sys.stdin,], [], []) 31 # 若是是用戶輸入命令了,sys.stdin發生變化 32 if sys.stdin in readlist: 33 # 獲取輸入的內容 34 input_cmd = sys.stdin.read(1) 35 # 將命令發送給服務器 36 channel.sendall(input_cmd) 37 38 # 服務器返回告終果,channel通道接受到結果,發生變化 select感知到 39 if channel in readlist: 40 # 獲取結果 41 result = channel.recv(1024) 42 # 斷開鏈接後退出 43 if len(result) == 0: 44 print("\r\n**** EOF **** \r\n") 45 break 46 # 輸出到屏幕 47 sys.stdout.write(result.decode()) 48 sys.stdout.flush() 49 50 # 關閉通道 51 channel.close() 52 # 關閉連接 53 trans.close()
7. 支持tab自動補全code
1 import paramiko 2 import os 3 import select 4 import sys 5 import tty 6 import termios 7 8 ''' 9 實現一個xshell登陸系統的效果,登陸到系統就不斷輸入命令同時返回結果 10 支持自動補全,直接調用服務器終端 11 12 ''' 13 # 創建一個socket 14 trans = paramiko.Transport(('192.168.2.129', 22)) 15 # 啓動一個客戶端 16 trans.start_client() 17 18 # 若是使用rsa密鑰登陸的話 19 ''' 20 default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') 21 prikey = paramiko.RSAKey.from_private_key_file(default_key_file) 22 trans.auth_publickey(username='super', key=prikey) 23 ''' 24 # 若是使用用戶名和密碼登陸 25 trans.auth_password(username='super', password='super') 26 # 打開一個通道 27 channel = trans.open_session() 28 # 獲取終端 29 channel.get_pty() 30 # 激活終端,這樣就能夠登陸到終端了,就和咱們用相似於xshell登陸系統同樣 31 channel.invoke_shell() 32 33 # 獲取原操做終端屬性 34 oldtty = termios.tcgetattr(sys.stdin) 35 try: 36 # 將如今的操做終端屬性設置爲服務器上的原生終端屬性,能夠支持tab了 37 tty.setraw(sys.stdin) 38 channel.settimeout(0) 39 40 while True: 41 readlist, writelist, errlist = select.select([channel, sys.stdin,], [], []) 42 # 若是是用戶輸入命令了,sys.stdin發生變化 43 if sys.stdin in readlist: 44 # 獲取輸入的內容,輸入一個字符發送1個字符 45 input_cmd = sys.stdin.read(1) 46 # 將命令發送給服務器 47 channel.sendall(input_cmd) 48 49 # 服務器返回告終果,channel通道接受到結果,發生變化 select感知到 50 if channel in readlist: 51 # 獲取結果 52 result = channel.recv(1024) 53 # 斷開鏈接後退出 54 if len(result) == 0: 55 print("\r\n**** EOF **** \r\n") 56 break 57 # 輸出到屏幕 58 sys.stdout.write(result.decode()) 59 sys.stdout.flush() 60 finally: 61 # 執行完後將如今的終端屬性恢復爲原操做終端屬性 62 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) 63 64 # 關閉通道 65 channel.close() 66 # 關閉連接 67 trans.close()
https://blog.csdn.net/songfreeman/article/details/50920767