問題1: b'Unable to execute command or shell on remote system: Failed to Execute process.\r\n’
解決方法:
這是因為在遠程執行Windows命令的時候,需要添加上cmd /c,如下所示:
問題2: 執行rmdir命令時報告錯誤: b'Invalid switch -
解決方法:
這是因為遠程調用rmdir命令刪除目錄時,目錄的路徑需要注意使用Windows路徑,但又由於Python對於Windows的反斜杠路徑支持不友好,需要在路徑字符串的處理時添加r作為前綴處理。如下提供的解決方法 r’E:\tsss':
問題3:執行遠程命令時報告 Permission denied
解決方法:
可能情況1: 通常該問題是由於遠程文件夾或文件的權限問題導致。比如目錄只讀權限,比如文件的用戶歸屬問題。這里只能說提供一個供參考的解決方式:使用freeSSHD搭建服務的時候添加遠程機器的管理員作為ssh的遠程訪問登錄用戶進行操作。(通常使用sftp容易出現問題,可以直接使用Windows系統命令處理,Unix/Linux也可以使用對應的系統命令)
可能情況2: 使用sftp上傳或下載文件時,包括刪除文件或目錄時,需要注意:
a. sftp只能刪除空目錄,所以如果要刪除目錄,先必須循環迭代刪除目錄中的文件(sftp.remove),再刪除目錄(sftp.rmdir)。
b. sftp的使用需要配合ssh服務設置的共享根目錄,比如如果使用了freesshd搭建了遠程機器的ssh服務,在配置了sftp的根目錄后,sftp對於遠程目錄路徑的操作需要使用相對路徑(相對於根目錄),而不是使用絕對路徑。
問題4: paramiko.ssh_exception.AuthenticationException: Authentication failed.
解決方法:
這是由於ssh遠程登錄的賬號或密碼不正確導致。
問題5:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa8 in position 54: invalid start byte
解決方法:
這通常是由於字符編碼導致的問題,根本原因是Paramiko的字符編碼寫的很死,在paramiko的py3compat.py包中存在一個u方法,其中將字符編碼寫死了,必須是’utf-8’,如果遇到中文之類的字符就會報錯。u方法如下所示:
可以將該u方法進行重寫,重寫如下所示:
1 def u(s, encoding="utf8"): 2 """cast bytes or unicode to unicode""" 3 if isinstance(s, bytes): 4 try: 5 return s.decode(encoding) 6 except UnicodeDecodeError: 7 return s.decode('ISO-8859-1') 8 elif isinstance(s, str): 9 return s 10 else: 11 raise TypeError("Expected unicode or bytes, got {!r}".format(s))
問題6: ssh_client.exec_command執行很長時間卡住,沒有任何輸出
解決方法:這可能是因為執行的命令返回的輸出內容很大,導致無法及時打印。解決方法可以使用channel輪回查詢的方式,代碼參考如下:
1 import sys 2 import time 3 import select 4 import paramiko 5 6 host = 'test.example.com' 7 i = 1 8 9 # 10 # Try to connect to the host. 11 # Retry a few times if it fails. 12 # 13 while True: 14 print "Trying to connect to %s (%i/30)" % (host, i) 15 16 try: 17 ssh = paramiko.SSHClient() 18 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 19 ssh.connect(host) 20 print "Connected to %s" % host 21 break 22 except paramiko.AuthenticationException: 23 print "Authentication failed when connecting to %s" % host 24 sys.exit(1) 25 except: 26 print "Could not SSH to %s, waiting for it to start" % host 27 i += 1 28 time.sleep(2) 29 30 # If we could not connect within time limit 31 if i == 30: 32 print "Could not connect to %s. Giving up" % host 33 sys.exit(1) 34 35 # Send the command (non-blocking) 36 stdin, stdout, stderr = ssh.exec_command("my_long_command --arg 1 --arg 2") 37 38 # Wait for the command to terminate 39 while not stdout.channel.exit_status_ready(): 40 # Only print data if there is data to read in the channel 41 if stdout.channel.recv_ready(): 42 rl, wl, xl = select.select([stdout.channel], [], [], 0.0) 43 if len(rl) > 0: 44 # Print data from stdout 45 print stdout.channel.recv(1024), 46 47 # 48 # Disconnect from the host 49 # 50 print "Command done, closing SSH connection" 51 ssh.close()
該方案轉自:http://sebastiandahlgren.se/2012/10/11/using-paramiko-to-send-ssh-commands/