paramiko结合stdout和stderr

Dan*_*elS 11 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.)
Run Code Online (Sandbox Code Playgroud)

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

错误:频道已关闭.

任何帮助将不胜感激

Geo*_*rge 16

虽然set_combine_stderr转移stderrstdout流是真的,它会以混乱的顺序进行,所以你不会得到你可能想要的结果,即按照写入顺序组合的行,就好像你在本地终端窗口中运行命令一样.相反,使用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]))
Run Code Online (Sandbox Code Playgroud)

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

#!/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()
Run Code Online (Sandbox Code Playgroud)

如果你运行上面的命令,你应该按顺序看到100行.相反,如果您注释掉该chan.get_pty()调用并取消注释该chan.set_combine_stderr(True)调用,您将获得从运行到运行随机散布的数量stdoutstderr线条.


rob*_*aos 5

好的,我知道这是一个很老的话题,但我遇到了同样的问题,我得到了一个(也许不是那么)漂亮的解决方案。只需调用远程服务器上的命令将 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()
Run Code Online (Sandbox Code Playgroud)


Dan*_*elS 3

@AaronMcSmooth:我指的是我正在连接的计算机的标准输出和标准错误(通过 SSH)。

我最终这样做了:

stdin, stdout, stderr = ssh.exec_command(...)

output = stdin.read().strip() + stdout.read().strip()
Run Code Online (Sandbox Code Playgroud)

出于我的应用程序的目的,区分 stdout 和 stderr 并不重要,但我认为这不是结合两者的最佳方式。

的代码SSHClient.exec_command()是(查看paramiko的源代码):

def exec_command(self, command, bufsize=-1):
    chan = self._transport.open_session() 
    chan.exec_command(command) 
    stdin = chan.makefile('wb', bufsize) 
    stdout = chan.makefile('rb', bufsize) 
    stderr = chan.makefile_stderr('rb', bufsize) 
    return stdin, stdout, stderr
Run Code Online (Sandbox Code Playgroud)

我在通道上执行相同的操作,但收到通道已关闭错误。

  • 看起来您正在尝试从“stdin”读取?我想你可能想从“stderr”中读取。 (2认同)