【问题标题】:How to connect Paramiko stdin, stdout and stderr to console?如何将 Paramiko 标准输入、标准输出和标准错误连接到控制台?
【发布时间】:2019-09-03 04:59:22
【问题描述】:

我使用 Paramiko Python 包通过 SSH 运行命令。我可以将输出输出到 stdout,但是如何正确地将 stdout、stderr 和 stdin 重定向到 sys ?

下面的代码只会在标准输出上显示“stdout1”和“stdout2”。我如何正确获得“stderr”?最好还支持标准输入?

import paramiko
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.connect("localhost")
stdin, stdout, stderr = ssh.exec_command("echo stdout1 >&1; echo stderr >&2; echo stdout2 >&1")
ch = stdout.channel
while True:
    bs = ch.recv(1)
    if not bs:
        break
    print(bs.decode("utf-8"), end="")

【问题讨论】:

    标签: python paramiko


    【解决方案1】:

    您可以阅读来自ChannelFile (http://docs.paramiko.org/en/2.4/api/channel.html?highlight=stdout#paramiko.channel.ChannelFile) 的行。

    例子:

    stdin, stdout, stderr = ssh.exec_command("echo stdout1 >&1; echo stderr >&2; echo stdout2 >&1")
    
    while True:
        print(stdout.read().decode(), end='')
        if stdout.channel.exit_status_ready():
            break
    
    while True:
        print(stderr.read().decode(), end='')
        if stderr.channel.exit_status_ready():
            break
    

    此解决方案有一些缺点,其中详细描述了: Paramiko recv()/read()/readline(s)() on stderr returns empty string.

    【讨论】:

    • 该解决方案的问题是“stdout2”在“stderr”之前打印。我找到了一个名为 asyncssh 的替代包,它更容易用于我的用例。
    【解决方案2】:

    我发现 asyncssh 更适合我。以下代码按预期工作:

    import asyncssh
    import asyncio
    import sys
    
    async def run():
        async with asyncssh.connect('localhost') as ssh:
            await ssh.run("echo stdout1 >&1; echo stderr >&2; echo stdout2 >&1",
                          stdout=sys.stdout,
                          stderr=sys.stderr)
    
    asyncio.run(run())
    

    【讨论】:

      猜你喜欢
      • 2010-09-21
      • 2014-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 2011-03-24
      相关资源
      最近更新 更多