如何将Paramiko stdin,stdout和stderr连接到控制台



我使用Paramiko Python包通过SSH运行命令。我可以输出到标准输出,但是我怎样才能正确地将标准输出、标准输出和标准输入重定向到系统输出?

下面的代码只会在标准输出上显示"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="")

你可以阅读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 返回空字符串。

我发现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())

最新更新