我正在尝试将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()):
错误:频道已关闭。
非常感谢任何帮助
答案 0 :(得分:15)
虽然set_combine_stderr
确实将stderr
转移到stdout
流,但它是以混乱的顺序转移,所以你没有得到你可能想要的结果,即行按照写入的顺序组合,就好像您在本地终端窗口中运行命令一样。相反,请使用get_pty
。这将导致服务器通过伪终端运行线路,按时间顺序保持它们。
这是一个测试程序outerr.py
,用于在stdout
和stdin
上写入交替的行。假设它位于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)
来电,那么您将从运行中随机散布stdout
和stderr
条线。
答案 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()