26 Python模塊之paramiko

  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 

相關文章
相關標籤/搜索