2010-08-25 600 views
64
client = paramiko.SSHClient() 
stdin, stdout, stderr = client.exec_command(command) 

有什麼辦法可以得到命令的返回碼嗎?如何使用Paramiko獲得SSH返回碼?

很難解析所有的標準輸出/標準錯誤,並知道命令是否成功完成。

回答

42

SSHClient是Paramiko中較低級功能的簡單包裝類。 API documentation在Channel類上列出了一個recv_exit_status()方法。

一個非常簡單的演示腳本:

$ cat sshtest.py 
import paramiko 
import getpass 

pw = getpass.getpass() 

client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.WarningPolicy()) 
client.connect('127.0.0.1', password=pw) 

while True: 
    cmd = raw_input("Command to run: ") 
    if cmd == "": 
     break 
    chan = client.get_transport().open_session() 
    print "running '%s'" % cmd 
    chan.exec_command(cmd) 
    print "exit status: %s" % chan.recv_exit_status() 

client.close() 

$ python sshtest.py 
Password: 
Command to run: true 
running 'true' 
exit status: 0 
Command to run: false 
running 'false' 
exit status: 1 
Command to run: 
$ 
+0

真的很感謝您的回答!我在我的項目中使用它。 非常感謝。到目前爲止,我可以使用paramiko而不是使用python編程系統命令ssh。 – Beyonder 2010-08-25 10:11:05

+0

這只是我通過查看SSHClient的來源而放在一起的,因此它可能不是最優的*。順便說一句:如果這樣做你想要的,你可能想「接受」我的答案。 – JanC 2010-08-25 15:58:19

+0

鏈接死亡請更新 – 2015-04-17 08:37:12

195

很多簡單的例子,不涉及直接調用通道類:

import paramiko 

client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
client.connect('blahblah.com') 

stdin, stdout, stderr = client.exec_command("uptime") 
print stdout.channel.recv_exit_status() # status is 0 

stdin, stdout, stderr = client.exec_command("oauwhduawhd") 
print stdout.channel.recv_exit_status() # status is 127 
+29

這是問題的正確解決方案。 – gphilip 2013-10-24 19:18:18

+1

關於這個例子,*不錯的*就是捕獲不僅僅是EXIT(就像問題所要求的那樣),但是展示你仍然可以獲得STDOUT和STDERR。 多年前,我被Paramiko貧乏的示例代碼庫(沒有不敬)所迷惑,並且讓EXIT I使用低級的transport()調用。 transport()似乎強迫你「挑選一個」(這可能不是真的,但缺乏示例和教程文檔使我相信)... – 2015-12-10 18:19:33

5

感謝JanC,我加了一些修改的例子,在Python3中測試,它對我來說真的很有用。

import paramiko 
import getpass 

pw = getpass.getpass() 

client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.WarningPolicy()) 
#client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 

def start(): 
    try : 
     client.connect('127.0.0.1', port=22, username='ubuntu', password=pw) 
     return True 
    except Exception as e: 
     #client.close() 
     print(e) 
     return False 

while start(): 
    key = True 
    cmd = input("Command to run: ") 
    if cmd == "": 
     break 
    chan = client.get_transport().open_session() 
    print("running '%s'" % cmd) 
    chan.exec_command(cmd) 
    while key: 
     if chan.recv_ready(): 
      print("recv:\n%s" % chan.recv(4096).decode('ascii')) 
     if chan.recv_stderr_ready(): 
      print("error:\n%s" % chan.recv_stderr(4096).decode('ascii')) 
     if chan.exit_status_ready(): 
      print("exit status: %s" % chan.recv_exit_status()) 
      key = False 
      client.close() 
client.close() 
+0

我們是否會收到任何錯誤消息 - 如果有的話 - 在chan.recv_stderr_ready ()? chan.recv_stderr(4096).decode('ascii')是否返回消息文本? – kten 2017-09-07 11:24:37