[轉]python3之paramiko模組(基於ssh連線進行遠端登入伺服器執行命令和上傳下載檔案的功能)
阿新 • • 發佈:2018-12-19
轉自:https://www.cnblogs.com/zhangxinqi/p/8372774.html
閱讀目錄
回到頂部1、paramiko模組介紹
paramiko模組提供了基於ssh連線,進行遠端登入伺服器執行命令和上傳下載檔案的功能。這是一個第三方的軟體包,使用之前需要安裝。
回到頂部2、paramiko的使用方法
(1)基於使用者名稱和密碼的sshclient方式登陸
#!/usr/bin/env python #coding:utf8 import paramiko #建立sshclient物件 ssh = paramiko.SSHClient() #允許將信任的主機自動加入到host_allow 列表,此方法必須放在connect方法的前面 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #呼叫connect方法連線伺服器 ssh.connect(hostname='172.16.32.129',port=2323,username='root',password='123.com') while True: input_command = input('>>>:') if input_command == 'quit': break #執行命令,輸出結果在stdout中,如果是錯誤則放在stderr中 stdin,stdout,stderr = ssh.exec_command(input_command) result = stdout.read() #read方法讀取輸出結果 if len(result) == 0: #判斷如果輸出結果長度等於0表示為錯誤輸出print(stderr.read()) else: print(str(result,'utf-8')) ssh.close()
封裝方法,隱藏屬性:
#config.ini檔案 [ssh] host=172.16.32.129 port=2323 user=root pwd=123.com timeout=1.1 #封裝ssh類 #!/usr/bin/env python #coding:utf8 import configparser,paramiko class parmikoclient(object): def __init__(self,ini_file): self.config=configparser.ConfigParser() self.config.read(ini_file) self.host = self.config.get('ssh','host') self.port = self.config.get('ssh', 'port') self.user = self.config.get('ssh', 'user') self.pwd = self.config.get('ssh', 'pwd') self.timeout = self.config.get('ssh', 'timeout') self.client=paramiko.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.client.connect(hostname=self.host,port=self.port,username=self.user,password=self.pwd,timeout=float(self.timeout)) def run_ssh(self,cmd_command): # 執行命令,輸出結果在stdout中,如果是錯誤則放在stderr中 stdin,stdout,stderr = self.client.exec_command(cmd_command) result = stdout.read() # read方法讀取輸出結果 if len(result) == 0: # 判斷如果輸出結果長度等於0表示為錯誤輸出 print(stderr.read().decode()) else: print(str(result, 'utf-8')) def close(self): self.client.close() if __name__ == '__main__': client_cmd = parmikoclient('config.ini') while True: cmd_input=input('>>>:') client_cmd.run_ssh(cmd_input) if cmd_input == 'quit': client_cmd.close()
通過transport方式登入:
#!/usr/bin/env python #coding:utf8 import paramiko #例項化一個transport物件 transport = paramiko.Transport(('172.16.32.129',2323)) #建立連線 transport.connect(username='root',password='123') #建立ssh物件 ssh = paramiko.SSHClient() #繫結transport到ssh物件 ssh._transport=transport #執行命令 stdin,stdout,stderr=ssh.exec_command('df') #列印輸出 print(stdout.read().decode()) #關閉連線 transport.close()
(2)基於金鑰的sshclient方式登陸
#!/usr/bin/env python #coding:utf8 #必須先將公鑰檔案傳輸到伺服器的~/.ssh/authorized_keys中 import paramiko # 指定本地的RSA私鑰檔案,如果建立金鑰對時設定的有密碼,password為設定的密碼,如無不用指定password引數 pkey = paramiko.RSAKey.from_private_key_file('id_rsa_1024') #建立連線 ssh = paramiko.SSHClient() #允許將信任的主機自動加入到known_hosts列表 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname='172.16.32.129',port=2323,username='root',pkey=pkey) #指定金鑰連線 #執行命令 stdin,stdout,stderr=ssh.exec_command('free -m') print(stdout.read().decode()) ssh.close()
以上需要確保被訪問的伺服器對應使用者.ssh目錄下有authorized_keys檔案,也就是將伺服器上生成的公鑰檔案儲存為authorized_keys。並將私鑰檔案作為paramiko的登陸金鑰
transport封裝金鑰登陸:
#!/usr/bin/env python #coding:utf8 #必須先將公鑰檔案傳輸到伺服器的~/.ssh/authorized_keys中 import paramiko # 指定本地的RSA私鑰檔案,如果建立金鑰對時設定的有密碼,password為設定的密碼,如無不用指定password引數 pkey = paramiko.RSAKey.from_private_key_file('id_rsa_1024') #建立transport物件繫結主機和埠,指定使用者和金鑰連線 transport = paramiko.Transport(('172.16.32.129',2323)) transport.connect(username='root',pkey=pkey) ssh = paramiko.SSHClient() ssh._transport = transport #類屬性賦值 #允許將信任的主機自動加入到known_hosts列表 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #執行命令 stdin,stdout,stderr=ssh.exec_command('free -m') print(stdout.read().decode()) ssh.close()
(3)SFTP檔案傳輸
#!/usr/bin/env python #coding:utf8 import paramiko #例項化transport物件,並建立連線 transport = paramiko.Transport(('172.16.32.129',2323)) transport.connect(username='root',password='123.com') #例項化sftp物件,指定連線物件 sftp = paramiko.SFTPClient.from_transport(transport) #上傳檔案 sftp.put(localpath='id_rsa_1024',remotepath='/root/idrsa1024.txt') #下載檔案 sftp.get(remotepath='/root/idrsa1024.txt',localpath='idrsa1024_back.txt') #關閉連線 transport.close()
實現一個類似xshell工具的功能,登入以後可以輸入命令回車後就返回結果:
import paramiko import os import select import sys # 建立一個socket trans = paramiko.Transport(('192.168.2.129', 22)) # 啟動一個客戶端 trans.start_client() # 如果使用rsa金鑰登入的話 ''' default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') prikey = paramiko.RSAKey.from_private_key_file(default_key_file) trans.auth_publickey(username='super', key=prikey) ''' # 如果使用使用者名稱和密碼登入 trans.auth_password(username='super', password='super') # 開啟一個通道 channel = trans.open_session() # 獲取終端 channel.get_pty() # 啟用終端,這樣就可以登入到終端了,就和我們用類似於xshell登入系統一樣 channel.invoke_shell() # 下面就可以執行你所有的操作,用select實現 # 對輸入終端sys.stdin和 通道進行監控, # 當用戶在終端輸入命令後,將命令交給channel通道,這個時候sys.stdin就發生變化,select就可以感知 # channel的傳送命令、獲取結果過程其實就是一個socket的傳送和接受資訊的過程 while True: readlist, writelist, errlist = select.select([channel, sys.stdin,], [], []) # 如果是使用者輸入命令了,sys.stdin發生變化 if sys.stdin in readlist: # 獲取輸入的內容 input_cmd = sys.stdin.read(1) # 將命令傳送給伺服器 channel.sendall(input_cmd) # 伺服器返回了結果,channel通道接受到結果,發生變化 select感知到 if channel in readlist: # 獲取結果 result = channel.recv(1024) # 斷開連線後退出 if len(result) == 0: print("\r\n**** EOF **** \r\n") break # 輸出到螢幕 sys.stdout.write(result.decode()) sys.stdout.flush() # 關閉通道 channel.close() # 關閉連結 trans.close()
支援tab自動補全
import paramiko import os import select import sys import tty import termios ''' 實現一個xshell登入系統的效果,登入到系統就不斷輸入命令同時返回結果 支援自動補全,直接呼叫伺服器終端 ''' # 建立一個socket trans = paramiko.Transport(('192.168.2.129', 22)) # 啟動一個客戶端 trans.start_client() # 如果使用rsa金鑰登入的話 ''' default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') prikey = paramiko.RSAKey.from_private_key_file(default_key_file) trans.auth_publickey(username='super', key=prikey) ''' # 如果使用使用者名稱和密碼登入 trans.auth_password(username='super', password='super') # 開啟一個通道 channel = trans.open_session() # 獲取終端 channel.get_pty() # 啟用終端,這樣就可以登入到終端了,就和我們用類似於xshell登入系統一樣 channel.invoke_shell() # 獲取原操作終端屬性 oldtty = termios.tcgetattr(sys.stdin) try: # 將現在的操作終端屬性設定為伺服器上的原生終端屬性,可以支援tab了 tty.setraw(sys.stdin) channel.settimeout(0) while True: readlist, writelist, errlist = select.select([channel, sys.stdin,], [], []) # 如果是使用者輸入命令了,sys.stdin發生變化 if sys.stdin in readlist: # 獲取輸入的內容,輸入一個字元傳送1個字元 input_cmd = sys.stdin.read(1) # 將命令傳送給伺服器 channel.sendall(input_cmd) # 伺服器返回了結果,channel通道接受到結果,發生變化 select感知到 if channel in readlist: # 獲取結果 result = channel.recv(1024) # 斷開連線後退出 if len(result) == 0: print("\r\n**** EOF **** \r\n") break # 輸出到螢幕 sys.stdout.write(result.decode()) sys.stdout.flush() finally: # 執行完後將現在的終端屬性恢復為原操作終端屬性 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) # 關閉通道 channel.close() # 關閉連結 trans.close()
標籤: python 好文要頂 關注我 收藏該文 Py.qi
關注 - 9
粉絲 - 70 +加關注 0 0 « 上一篇: python3之redis
» 下一篇: python3之協程
轉自:https://www.cnblogs.com/zhangxinqi/p/8372774.html
閱讀目錄
回到頂部1、paramiko模組介紹
paramiko模組提供了基於ssh連線,進行遠端登入伺服器執行命令和上傳下載檔案的功能。這是一個第三方的軟體包,使用之前需要安裝。
回到頂部2、paramiko的使用方法
(1)基於使用者名稱和密碼的sshclient方式登陸
#!/usr/bin/env python #coding:utf8 import paramiko #建立sshclient物件 ssh = paramiko.SSHClient() #允許將信任的主機自動加入到host_allow 列表,此方法必須放在connect方法的前面 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #呼叫connect方法連線伺服器 ssh.connect(hostname='172.16.32.129',port=2323,username='root',password='123.com') while True: input_command = input('>>>:') if input_command == 'quit': break #執行命令,輸出結果在stdout中,如果是錯誤則放在stderr中 stdin,stdout,stderr = ssh.exec_command(input_command) result = stdout.read() #read方法讀取輸出結果 if len(result) == 0: #判斷如果輸出結果長度等於0表示為錯誤輸出 print(stderr.read()) else: print(str(result,'utf-8')) ssh.close()
封裝方法,隱藏屬性:
#config.ini檔案 [ssh] host=172.16.32.129 port=2323 user=root pwd=123.com timeout=1.1 #封裝ssh類 #!/usr/bin/env python #coding:utf8 import configparser,paramiko class parmikoclient(object): def __init__(self,ini_file): self.config=configparser.ConfigParser() self.config.read(ini_file) self.host = self.config.get('ssh','host') self.port = self.config.get('ssh', 'port') self.user = self.config.get('ssh', 'user') self.pwd = self.config.get('ssh', 'pwd') self.timeout = self.config.get('ssh', 'timeout') self.client=paramiko.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.client.connect(hostname=self.host,port=self.port,username=self.user,password=self.pwd,timeout=float(self.timeout)) def run_ssh(self,cmd_command): # 執行命令,輸出結果在stdout中,如果是錯誤則放在stderr中 stdin,stdout,stderr = self.client.exec_command(cmd_command) result = stdout.read() # read方法讀取輸出結果 if len(result) == 0: # 判斷如果輸出結果長度等於0表示為錯誤輸出 print(stderr.read().decode()) else: print(str(result, 'utf-8')) def close(self): self.client.close() if __name__ == '__main__': client_cmd = parmikoclient('config.ini') while True: cmd_input=input('>>>:') client_cmd.run_ssh(cmd_input) if cmd_input == 'quit': client_cmd.close()
通過transport方式登入:
#!/usr/bin/env python #coding:utf8 import paramiko #例項化一個transport物件 transport = paramiko.Transport(('172.16.32.129',2323)) #建立連線 transport.connect(username='root',password='123') #建立ssh物件 ssh = paramiko.SSHClient() #繫結transport到ssh物件 ssh._transport=transport #執行命令 stdin,stdout,stderr=ssh.exec_command('df') #列印輸出 print(stdout.read().decode()) #關閉連線 transport.close()
(2)基於金鑰的sshclient方式登陸
#!/usr/bin/env python #coding:utf8 #必須先將公鑰檔案傳輸到伺服器的~/.ssh/authorized_keys中 import paramiko # 指定本地的RSA私鑰檔案,如果建立金鑰對時設定的有密碼,password為設定的密碼,如無不用指定password引數 pkey = paramiko.RSAKey.from_private_key_file('id_rsa_1024') #建立連線 ssh = paramiko.SSHClient() #允許將信任的主機自動加入到known_hosts列表 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname='172.16.32.129',port=2323,username='root',pkey=pkey) #指定金鑰連線 #執行命令 stdin,stdout,stderr=ssh.exec_command('free -m') print(stdout.read().decode()) ssh.close()
以上需要確保被訪問的伺服器對應使用者.ssh目錄下有authorized_keys檔案,也就是將伺服器上生成的公鑰檔案儲存為authorized_keys。並將私鑰檔案作為paramiko的登陸金鑰
transport封裝金鑰登陸:
#!/usr/bin/env python #coding:utf8 #必須先將公鑰檔案傳輸到伺服器的~/.ssh/authorized_keys中 import paramiko # 指定本地的RSA私鑰檔案,如果建立金鑰對時設定的有密碼,password為設定的密碼,如無不用指定password引數 pkey = paramiko.RSAKey.from_private_key_file('id_rsa_1024') #建立transport物件繫結主機和埠,指定使用者和金鑰連線 transport = paramiko.Transport(('172.16.32.129',2323)) transport.connect(username='root',pkey=pkey) ssh = paramiko.SSHClient() ssh._transport = transport #類屬性賦值 #允許將信任的主機自動加入到known_hosts列表 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #執行命令 stdin,stdout,stderr=ssh.exec_command('free -m') print(stdout.read().decode()) ssh.close()
(3)SFTP檔案傳輸
#!/usr/bin/env python #coding:utf8 import paramiko #例項化transport物件,並建立連線 transport = paramiko.Transport(('172.16.32.129',2323)) transport.connect(username='root',password='123.com') #例項化sftp物件,指定連線物件 sftp = paramiko.SFTPClient.from_transport(transport) #上傳檔案 sftp.put(localpath='id_rsa_1024',remotepath='/root/idrsa1024.txt') #下載檔案 sftp.get(remotepath='/root/idrsa1024.txt',localpath='idrsa1024_back.txt') #關閉連線 transport.close()
實現一個類似xshell工具的功能,登入以後可以輸入命令回車後就返回結果:
import paramiko import os import select import sys # 建立一個socket trans = paramiko.Transport(('192.168.2.129', 22)) # 啟動一個客戶端 trans.start_client() # 如果使用rsa金鑰登入的話 ''' default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') prikey = paramiko.RSAKey.from_private_key_file(default_key_file) trans.auth_publickey(username='super', key=prikey) ''' # 如果使用使用者名稱和密碼登入 trans.auth_password(username='super', password='super') # 開啟一個通道 channel = trans.open_session() # 獲取終端 channel.get_pty() # 啟用終端,這樣就可以登入到終端了,就和我們用類似於xshell登入系統一樣 channel.invoke_shell() # 下面就可以執行你所有的操作,用select實現 # 對輸入終端sys.stdin和 通道進行監控, # 當用戶在終端輸入命令後,將命令交給channel通道,這個時候sys.stdin就發生變化,select就可以感知 # channel的傳送命令、獲取結果過程其實就是一個socket的傳送和接受資訊的過程 while True: readlist, writelist, errlist = select.select([channel, sys.stdin,], [], []) # 如果是使用者輸入命令了,sys.stdin發生變化 if sys.stdin in readlist: # 獲取輸入的內容 input_cmd = sys.stdin.read(1) # 將命令傳送給伺服器 channel.sendall(input_cmd) # 伺服器返回了結果,channel通道接受到結果,發生變化 select感知到 if channel in readlist: # 獲取結果 result = channel.recv(1024) # 斷開連線後退出 if len(result) == 0: print("\r\n**** EOF **** \r\n") break # 輸出到螢幕 sys.stdout.write(result.decode()) sys.stdout.flush() # 關閉通道 channel.close() # 關閉連結 trans.close()
支援tab自動補全
import paramiko import os import select import sys import tty import termios ''' 實現一個xshell登入系統的效果,登入到系統就不斷輸入命令同時返回結果 支援自動補全,直接呼叫伺服器終端 ''' # 建立一個socket trans = paramiko.Transport(('192.168.2.129', 22)) # 啟動一個客戶端 trans.start_client() # 如果使用rsa金鑰登入的話 ''' default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') prikey = paramiko.RSAKey.from_private_key_file(default_key_file) trans.auth_publickey(username='super', key=prikey) ''' # 如果使用使用者名稱和密碼登入 trans.auth_password(username='super', password='super') # 開啟一個通道 channel = trans.open_session() # 獲取終端 channel.get_pty() # 啟用終端,這樣就可以登入到終端了,就和我們用類似於xshell登入系統一樣 channel.invoke_shell() # 獲取原操作終端屬性 oldtty = termios.tcgetattr(sys.stdin) try: # 將現在的操作終端屬性設定為伺服器上的原生終端屬性,可以支援tab了 tty.setraw(sys.stdin) channel.settimeout(0) while True: readlist, writelist, errlist = select.select([channel, sys.stdin,], [], []) # 如果是使用者輸入命令了,sys.stdin發生變化 if sys.stdin in readlist: # 獲取輸入的內容,輸入一個字元傳送1個字元 input_cmd = sys.stdin.read(1) # 將命令傳送給伺服器 channel.sendall(input_cmd) # 伺服器返回了結果,channel通道接受到結果,發生變化 select感知到 if channel in readlist: # 獲取結果 result = channel.recv(1024) # 斷開連線後退出 if len(result) == 0: print("\r\n**** EOF **** \r\n") break # 輸出到螢幕 sys.stdout.write(result.decode()) sys.stdout.flush() finally: # 執行完後將現在的終端屬性恢復為原操作終端屬性 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) # 關閉通道 channel.close() # 關閉連結 trans.close()