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

How to connect Paramiko stdin, stdout and stderr to console?

我使用 Paramiko Python 包通过 SSH 执行 运行 命令。我可以将输出输出到 stdout,但我怎样才能正确地将 stdout、stderr 和 stdin 重定向到 sys one?

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

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