2010-08-25 598 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