paramiko结合stdout和std

2024-04-29 15:05:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试合并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())会出现以下错误:

Error: Channel closed.

任何帮助都将不胜感激


Tags: and对象paramikoconnectstderrstdoutchannelok
3条回答

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

虽然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行的簇随机分布。

@AaronMcSmooth:我指的是我正在连接的计算机的stdout和stderr(通过SSH)。

我最后这样做了:

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

output = stdin.read().strip() + stdout.read().strip()

就我的应用程序而言,区分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

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

相关问题 更多 >