paramiko 结合了 stdout 和 stderr

发布于 2024-09-25 14:16:07 字数 441 浏览 1 评论 0原文

我正在尝试合并 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() ):

错误:频道已关闭。

任何帮助将不胜感激

I am trying to combine the output of stdout and stderr. My belief is that this can be done with the set_combine_stderr() of a Channel object.

This is what I am doing:

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.)

However, I get the following error when I try to store the result (last line above, chan.makefile() ):

Error: Channel closed.

Any help would be greatly appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半葬歌 2024-10-02 14:16:07

虽然 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) 调用,您将得到一堆 stdout code> 和 stderr 行在运行之间随机散布。

While it is true that set_combine_stderr diverts stderr to the stdout stream, it does so in chaotic order, so you do not get the result you probably want, namely, the lines combined in the order written, as if you were running the command in a local terminal window. Instead, use get_pty. That will cause the server to run the lines through a pseudo-terminal, keeping them in chronological sequence.

Here's a test program, outerr.py, that writes alternating lines on stdout and stdin. Assume it's sitting in the home directory of 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]))

Now try the following code to run it remotely:

#!/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()

If you run the above, you should see 100 lines in order as written. If, instead, you comment out the chan.get_pty() call and uncomment the chan.set_combine_stderr(True) call, you will get clumps of stdout and stderr lines interspersed randomly from run to run.

黒涩兲箜 2024-10-02 14:16:07

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

Ok, I know this is quite an old topic, but I run into the same problem and I got a (maybe not-so-)pretty solution. Just call the command on the remote server redirecting the stderr to stdout and then always read from the stdout. For example:

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()
绿光 2024-10-02 14:16:07

@AaronMcSmooth:我指的是我正在连接的计算机的标准输出和标准错误(通过 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

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

@AaronMcSmooth: I am referring to the stdout and stderr of the computer I am connecting to (via SSH).

I ended up doing this:

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

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

For the purpose of my application, it doesn't matter to distinguish between stdout and stderr, but I don't think that's the best way to combine the two.

The code of SSHClient.exec_command() is (looking at paramiko's source code):

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

I am performing the same actions on the channel but receive the Channel is closed error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文