Как подключить Paramiko stdin, stdout и stderr к консоли? - PullRequest
2 голосов
/ 12 апреля 2019

Я использую пакет Paramiko Python для запуска команд через SSH. Я могу получить вывод на stdout, но как правильно перенаправить stdout, stderr и stdin на sys?

Приведенный ниже код будет отображать только "stdout1" и "stdout2" на stdout. Как я могу получить "stderr" там правильно? И желательно также поддержку stdin?

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="")

Ответы [ 2 ]

0 голосов
/ 19 апреля 2019

Я нашел 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())
0 голосов
/ 14 апреля 2019

Вы можете читать строки из 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) () в stderr возвращает пустую строку .

...