paramiko结合stdout和stderr

时间:2010-09-29 16:44:08

标签: python ssh paramiko

我正在尝试将stdout和stderr的输出结合起来。我相信这可以通过Channel对象的set_combine_stderr()完成。

这就是我在做的事情:

SSH = paramiko.SSHClient()
#I connect and everything OK, then:
chan = ssh.invoke_shell()
chan.set_combine_stderr(True)
chan.exec_command('python2.6 subir.py')
resultado = chan.makefile('rb', -1.)

但是,当我尝试存储结果时,我收到以下错误(上一行,chan.makefile()):

  

错误:频道已关闭。

非常感谢任何帮助

3 个答案:

答案 0 :(得分:15)

虽然set_combine_stderr确实将stderr转移到stdout流,但它是以混乱的顺序转移,所以你没有得到你可能想要的结果,即行按照写入的顺序组合,就好像您在本地终端窗口中运行命令一样。相反,请使用get_pty。这将导致服务器通过伪终端运行线路,按时间顺序保持它们。

这是一个测试程序outerr.py,用于在stdoutstdin上写入交替的行。假设它位于llmps @ meerkat2的主目录中。

#!/usr/bin/env python

import sys

for x in xrange(1, 101):
    (sys.stdout, sys.stderr)[x%2].write('This is line #%s, on std%s.\n' %
                (x, ('out', 'err')[x%2]))

现在尝试使用以下代码远程运行它:

#!/usr/bin/env python

import paramiko

def connect():
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('meerkat2', username='llmps', password='..')
    return ssh

def runTest(ssh):
    tran = ssh.get_transport()
    chan = tran.open_session()
    # chan.set_combine_stderr(True)
    chan.get_pty()
    f = chan.makefile()
    chan.exec_command('./outerr.py')
    print f.read(),

if __name__ == '__main__':
    ssh = connect()
    runTest(ssh)
    ssh.close()

如果运行上述内容,则应按顺序看到100行。相反,如果您注释掉chan.get_pty()来电并取消注释chan.set_combine_stderr(True)来电,那么您将从运行中随机散布stdoutstderr条线。

答案 1 :(得分:3)

答案 2 :(得分:1)

好的,我知道这是一个相当古老的话题,但我遇到了同样的问题,我得到了一个(可能不那么)漂亮的解决方案。只需调用远程服务器上的命令,将stderr重定向到stdout,然后始终从stdout读取。例如:

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('hostname', username='user', password='pass')

stdin,stdout,stderr = client.exec_command('python your_script.py 2> \&1')
print stdout.read()