一 、安裝
1.1、win10系統
安裝最新版本pip3后,使用pip3 install paramiko命令
E:\>pip3 install paramiko Collecting paramiko Downloading paramiko-2.8.0-py2.py3-none-any.whl (206 kB) |████████████████████████████████| 206 kB 24 kB/s Collecting cryptography>=2.5 Downloading cryptography-36.0.0-cp36-abi3-win_amd64.whl (2.2 MB) |████████████████████████████████| 2.2 MB 38 kB/s Collecting pynacl>=1.0.1 Downloading PyNaCl-1.4.0-cp35-abi3-win_amd64.whl (206 kB) |████████████████████████████████| 206 kB 16 kB/s Collecting bcrypt>=3.1.3 Downloading bcrypt-3.2.0-cp36-abi3-win_amd64.whl (28 kB) Requirement already satisfied: cffi>=1.12 in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from cryptography>=2.5->paramiko) (1.14.5) Requirement already satisfied: six in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from pynacl>=1.0.1->paramiko) (1.15.0) Requirement already satisfied: pycparser in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from cffi>=1.12->cryptography>=2.5->paramiko) (2.20) Installing collected packages: cryptography, pynacl, bcrypt, paramiko Successfully installed bcrypt-3.2.0 cryptography-36.0.0 paramiko-2.8.0 pynacl-1.4.0
1.2、centos系統
yum install python-paramiko
二、使用
參考鏈接:https://blog.csdn.net/liulanba/article/details/114596709
paramiko是用python語言寫的一個模塊,遠程連接到Linux服務器,查看上面的日志狀態,批量配置遠程服務器,文件上傳,文件下載等,提供了ssh及sftp進行遠程登錄服務器執行命令和上傳下載文件的功能。
2.1、基於用戶名和密碼實現SSH功能
import paramiko # 創建SSH對象 ssh = paramiko.SSHClient() # 允許連接不在known_hosts文件上的主機 # 即允許將信任的主機自動加入到host_allow 列表,此方法必須放在connect方法的前面 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 連接服務器 ssh.connect(hostname="192.168.0.99", port=22, username="root", password="rootroot") # 執行命令 stdin, stdout, stderr = ssh.exec_command('df') # 結果放到stdout中,如果有錯誤將放到stderr中 result = stdout.read().decode() # 獲取錯誤提示(stdout、stderr只會輸出其中一個) err = stderr.read() # 關閉連接 ssh.close() print(stdin, result, err)
2.2、基於用戶名和密碼的 transport 方式登錄
前一種方式是傳統的連接服務器、執行命令、關閉的一個操作,有時候需要登錄上服務器執行多個操作,比如執行命令、上傳/下載文件,上面方法則無法實現,可以通過如下方式來操作。
#SSHClient 封裝 Transport import paramiko # 實例化一個transport對象 transport = paramiko.Transport(('192.168.199.146', 22)) # 建立連接 transport.connect(username='fishman', password='9') # 將sshclient的對象的transport指定為以上的transport ssh = paramiko.SSHClient() ssh._transport = transport # 執行命令,和傳統方法一樣 stdin, stdout, stderr = ssh.exec_command('df') print (stdout.read().decode()) # 關閉連接 transport.close()
2.3、基於用戶名和密碼實現SFTP功能
import paramiko # 連接虛擬機centos上的ip及端口,實例化一個transport對象 transport = paramiko.Transport(("192.168.0.99", 22)) transport.connect(username="root", password="rootroot") # 將實例化的Transport作為參數傳入SFTPClient中 sftp = paramiko.SFTPClient.from_transport(transport) # 將“calculator.py”上傳到filelist文件夾中 sftp.put('D:\python庫\Python_shell\day05\calculator.py', '/filelist/calculator.py') # 將centos中的aaa.txt文件下載到桌面 sftp.get('/filedir/aaa.txt', r'C:\Users\duany_000\Desktop\test_aaa.txt') transport.close()
2.4、使用秘鑰實現SSH功能
import paramiko private_key = paramiko.RSAKey.from_private_key_file('id_rsa31') # 創建SSH對象 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 連接服務器 ssh.connect(hostname='192.168.79.9', port=22, username='root', pkey=private_key) stdin, stdout, stderr = ssh.exec_command('ifconfig') res_out = stdout.read() print(res_out.decode()) ssh.close()
2.5、基於密鑰的 Transport 方式登錄
# 指定本地的RSA私鑰文件,如果建立密鑰對時設置的有密碼,password為設定的密碼,如無不用指定password參數 pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345') # 建立連接 trans = paramiko.Transport(('192.168.2.129', 22)) trans.connect(username='super', pkey=pkey) # 將sshclient的對象的transport指定為以上的trans ssh = paramiko.SSHClient() ssh._transport = trans # 執行命令,和傳統方法一樣 stdin, stdout, stderr = ssh.exec_command('df -hl') print(stdout.read().decode()) # 關閉連接 trans.close()
2.6、使用秘鑰實現SFTP功能
import paramiko private_key = paramiko.RSAKey.from_private_key_file('id_rsa31') # 連接虛擬機centos上的ip及端口 transport = paramiko.Transport(("192.168.79.9", 22)) transport.connect(username="root", pkey=private_key) # 將實例化的Transport作為參數傳入SFTPClient中 sftp = paramiko.SFTPClient.from_transport(transport) # 將“calculator.py”上傳到filelist文件夾中 sftp.put('D:\python庫\Python_shell\day05\calculator.py', '/filedir/calculator.py') # 將centos中的aaa.txt文件下載到桌面 sftp.get('/filedir/oldtext.txt', r'C:\Users\duany_000\Desktop\oldtext.txt') transport.close()
2.7、實現輸入命令立馬返回結果的功能
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()
2.8、支持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()
2.9、exec_command()函數
官方解釋為
def exec_command( self, command, bufsize=-1, timeout=None, get_pty=False, environment=None, ): """ Execute a command on the SSH server. A new `.Channel` is opened and the requested command is executed. The command's input and output streams are returned as Python ``file``-like objects representing stdin, stdout, and stderr. :param str command: the command to execute :param int bufsize: interpreted the same way as by the built-in ``file()`` function in Python :param int timeout: set command's channel timeout. See `.Channel.settimeout` :param bool get_pty: Request a pseudo-terminal from the server (default ``False``). See `.Channel.get_pty` :param dict environment: a dict of shell environment variables, to be merged into the default environment that the remote command executes within. .. warning:: Servers may silently reject some environment variables; see the warning in `.Channel.set_environment_variable` for details. :return: the stdin, stdout, and stderr of the executing command, as a 3-tuple :raises: `.SSHException` -- if the server fails to execute the command .. versionchanged:: 1.10 Added the ``get_pty`` kwarg. """ chan = self._transport.open_session(timeout=timeout) if get_pty: chan.get_pty() chan.settimeout(timeout) if environment: chan.update_environment(environment) chan.exec_command(command) stdin = chan.makefile_stdin("wb", bufsize) stdout = chan.makefile("r", bufsize) stderr = chan.makefile_stderr("r", bufsize) return stdin, stdout, stderr
用法:
ssh.exec_command('cd /home/nvidia/lf && python test.py') print(stdout.read())
這種在命令完成后才顯示信息!但是,執行文件時,如果又不斷輸出,希望輸出一條打印一條,而不是在以后輸出,修改為:
# 執行命令 stdin, stdout, stderr = ssh.exec_command('cd /home/nvidia/lf && python test.py') for line in iter(stdout.readline, ""): print(line, end="") print('finished.')
import paramikoimport osimport selectimport sysimport ttyimport termios
'''實現一個xshell登錄系統的效果,登錄到系統就不斷輸入命令同時返回結果支持自動補全,直接調用服務器終端
'''# 建立一個sockettrans = 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()————————————————版權聲明:本文為CSDN博主「liulanba」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/liulanba/article/details/114596709