python之路-paramiko模塊


 paramiko

該模塊基於SSH用於連接遠程服務器並執行相關操作

SSHClient

遠程連接服務器有兩種方法:SSHClient、tranceport

用於連接遠程服務器並執行基本命令

基於用戶名密碼連接:

 1 import paramiko
 2 # 創建SSH對象
 3 ssh = paramiko.SSHClient()
 4 # 允許連接不在know_hosts文件中的主機
 5 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 6 # 連接服務器
 7 ssh.connect(hostname='192.168.247.131', port=22, username='root', password='111111')
 8 # 執行命令
 9 stdin, stdout, stderr = ssh.exec_command('pwd')
10 # 獲取命令結果
11 result = stdout.read()
12 print(result)
13 # 關閉連接
14 ssh.close() 

SSHClient封裝transport

 1 import paramiko
 2 
 3 transport = paramiko.Transport(('hostname', 22))
 4 transport.connect(username='wupeiqi', password='123')
 5 
 6 ssh = paramiko.SSHClient()
 7 ssh._transport = transport
 8 
 9 stdin, stdout, stderr = ssh.exec_command('df')
10 print stdout.read()
11 
12 transport.close()

基於公鑰密鑰連接:

 1 import paramiko
 2 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
 3 # 創建SSH對象
 4 ssh = paramiko.SSHClient()
 5 # 允許連接不在know_hosts文件中的主機
 6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 7 # 連接服務器
 8 ssh.connect(hostname='192.168.247.131', port=22, username='root', key=private_key)
 9 # 執行命令
10 stdin, stdout, stderr = ssh.exec_command('df')
11 # 獲取命令結果
12 result = stdout.read()
13 
14 
15 
16 # 關閉連接
17 
18 ssh.close()

封裝

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')

transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', pkey=private_key)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')

transport.close()

SFTPClient

實現文件下載的方法:Tranceport

用於連接遠程服務器並執行上傳下載

基於用戶名密碼上傳下載

 1 import paramiko
 2 
 3  
 4 
 5 transport = paramiko.Transport(('hostname',22))
 6 
 7 transport.connect(username='wupeiqi',password='123')
 8 
 9  
10 
11 sftp = paramiko.SFTPClient.from_transport(transport)
12 
13 # 將location.py 上傳至服務器 /tmp/test.py
14 
15 sftp.put('/tmp/location.py', '/tmp/test.py')
16 
17 # 將remove_path 下載到本地 local_path
18 
19 sftp.get('remove_path', 'local_path')
20 
21  
22 
23 transport.close()

基於公鑰密鑰上傳下載

import paramiko

 

private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')

 

transport = paramiko.Transport(('hostname', 22))

transport.connect(username='wupeiqi', pkey=private_key )

 

sftp = paramiko.SFTPClient.from_transport(transport)

# 將location.py 上傳至服務器 /tmp/test.py

sftp.put('/tmp/location.py', '/tmp/test.py')

# 將remove_path 下載到本地 local_path

sftp.get('remove_path', 'local_path')

 

transport.close()

通過以上分析,可以知道,如果想實現遠程連接執行命令,只能使用tranceport方法。

通過利用transport和SSHClient實現在一次鏈接中多次執行命令和上傳、下載文件。

 1 import paramiko
 2 import uuid
 3 class SSHConnection(object):
 4     def __init__(self,host='192.168.247.131',port=22,username='root',pwd='111111'):
 5         self.host = host
 6         self.port = port
 7         self.username = username
 8         self.pwd = pwd
 9         self._k = None
10 
11     def run(self):
12         self.connect()
13         pass
14         self.close()
15 
16     def connect(self):
17         transport = paramiko.Transport((self.host,self.port))
18         transport.connect(username=self.username,password=self.pwd)
19         self.__transport = transport
20     def close(self):
21         self.__transport.close()
22     def cmd(self,command):
23         ssh = paramiko.SSHClient()
24         ssh._transport = self.__transport
25         stdin,stdout,stderr = ssh.exec_command(command)
26         result = stdout.read()
27         return result
28     def upload(self,local_path,target_path):
29         sftp = paramiko.SFTPClient.from_transport(self.__transport)
30         sftp.put(local_path,target_path)
31 
32 def create_file(self):
33     file_name = str(uuid.uuid4())
34     with open(file_name, 'w') as f:
35         f.write('sb')
36     return file_name
37 ssh = SSHConnection()
38 #上傳文件、執行命令
39 ssh.connect()
40 r1 = ssh.cmd('df')
41 print(r1)
42 ssh.upload('s2.py','/home/s7.py')
43 ssh.close()

 上面的例子是將命令寫入代碼中,並返回執行結果,下面我們就來介紹通過終端輸入命令,等待返回結果:

1.輸入命令點回車,執行命令,等待結果(linux終端默認只有點擊回車,io中的stdin才會有變化),不支持tab補全

2.每輸入一個字就給服務器傳過去,然后再點回車,服務器執行傳來的命令。(改變終端的模式)

第一個實例

 

 1 import paramiko
 2 import sys
 3 import os
 4 import socket
 5 import select
 6 import getpass
 7 # from paramiko.py3compat import u   py27需要注釋
 8 tran = paramiko.Transport(('192.168.247.128',22,))
 9 tran.start_client()
10 tran.auth_password('root','111111')
11 #打開一個通道
12 chan = tran.open_session()
13 #獲取一個通道
14 chan.get_pty()
15 #激活器
16 chan.invoke_shell()
17 while True:
18     #監視用戶輸入和服務器返回數據
19     #sys.stdin 處理用戶輸入
20     #chan是之前創建的通道,用於就收服務器返回信息
21     readable,writeable,error = select.select([chan,sys.stdin,],[],[],1)
22     if chan in readable:        #此處的chan是服務器通過執行命令,返回的結果
23         try:
24             #x = u(chan.recv(1024))
25             x = chan.recv(1024)      #py27寫法
26             if len(x) == 0:
27                 print('\r\n*** EOF\r\n')
28                 break
29             sys.stdout.write(x)
30             sys.stdout.flush()         #刷新緩沖區,將內容打印到屏幕
31         except socket.timeout:
32             pass
33     if sys.stdin in readable:
34         inp = sys.stdin.readline()
35         chan.sendall(inp)
36 chan.close()
37 tran.close()

 

第二個實例

 1 import paramiko
 2 import sys
 3 import os
 4 import socket
 5 import select
 6 import getpass
 7 import tty
 8 import termios
 9 # from paramiko.py3compat import u   py27需要注釋
10 tran = paramiko.Transport(('192.168.247.128',22,))
11 tran.start_client()
12 tran.auth_password('lwq','123')
13 #打開一個通道
14 chan = tran.open_session()
15 #獲取一個通道
16 chan.get_pty()
17 #激活器
18 chan.invoke_shell()
19 #獲取原tty屬性,目的是為了在操作完以后恢復終端原型
20 oldtty = termios.tcgetattr(sys.stdin)
21 try:
22     #為tty設置新屬性
23     #默認當前tty設備屬性
24     #輸入一行回車,執行
25     #ctrl +c 進程退出,遇到特殊字符,特殊處理
26     #這是為原始模式,不認識特殊字符號
27     #放置特殊字符應用在當前終端,如此設置,將所有的用戶輸入均發送到 遠程服務器
28     tty.setraw(sys.stdin.fileno())
29     chan.settimeout(0.0)
30     while True:
31         #監視用戶輸入和服務器返回數據
32         #阻塞,直到句柄可讀
33         readable,writeable,error = select.select([chan,sys.stdin,],[],[],1)
34         if chan in readable:
35             try:
36                 #x = u(chan.recv(1024))
37                 x = chan.recv(1024)      #py27寫法
38                 if len(x) == 0:
39                     print('\r\n*** EOF\r\n')
40                     break
41                 sys.stdout.write(x)
42                 sys.stdout.flush()
43             except socket.timeout:
44                 pass
45         if sys.stdin in readable:
46             inp = sys.stdin.read(1)
47             if len(inp) == 0:
48                 break
49             chan.send(inp)
50 finally:
51     #重新設置終端屬性
52     termios.tcsetattr(sys.stdin,termios.TCSADRAIN,oldtty)
53 chan.close()
54 tran.close()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM