Как после выполнения команды Python Paramiko сохранить результат?

Как вы видите ниже, можно ли сохранить результат? Потому что во втором и третьем stdout.read() я не смог получить результат.

import paramiko
import os
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
dssh.connect('192.168.1.250', username='root', password='pass')
import os
stdin, stdout, stderr = dssh.exec_command('ifconfig')
print stdout.read()
print ('Sleeping 2 seconds!')
os.system('sleep 2')
stdin, stdout, stderr = dssh.exec_command('ls -l')
print stdout.read()
print stdout.read()
print stdout.read()
dssh.close()

person nightrider84    schedule 15.11.2011    source источник


Ответы (2)


Представьте, что stdout — это обычный файл. Что вы ожидаете получить, если позвоните file.read() во второй раз? -- ничего (пустая строка), если файл не изменился снаружи.

Чтобы сохранить строку:

output = stdout.read()

Вы можете найти Fabric более простым в использовании (он использует paramiko для выполнения команд под капотом).

person jfs    schedule 15.11.2011
comment
Я пробовал это раньше, и я не работал. Но теперь это работает. Хм? Спасибо, в любом случае - person nightrider84; 15.11.2011
comment
Если команда выдает также вывод на stderr, вам необходимо читать оба вывода параллельно. В противном случае, как только выходной буфер stderr заполнится, команда остановится, ожидая, пока вы прочитаете файл stderr. Если вместо этого вы продолжите чтение только с stdout, у вас возникнет тупик. - person Martin Prikryl; 15.06.2018
comment
@MartinPrikryl это верно для буферов канала ОС, например, если вы использовали subprocess.Popen. Я не уверен, что это применимо к потокам paramiko. Не могли бы вы предоставить полный минимальный пример кода, демонстрирующий взаимоблокировку? - person jfs; 15.06.2018
comment
Дело не в парамико, а в буферах на стороне сервера. Если ssh-клиент не использует вывод, ssh-сервер перестает читать вывод удаленной команды (что на самом деле эквивалентно subprocess.Popen, на который вы ссылаетесь). Например, это никогда не заканчивается в моей системе stdin, stdout, stderr = ssh.exec_command("for ((n=0;n<1000000;n++)); do echo 1234567890; done >&2") print stdout.read() - Если вы удалите >&2, оно завершится. - Хотя фактическое количество необходимых итераций будет варьироваться в зависимости от системы. - person Martin Prikryl; 15.06.2018
comment
Этот вопрос касается проблемы: Paramiko ssh умирает/зависает с большим выходом. - person Martin Prikryl; 15.10.2020

Вы можете попробовать этот универсальный API

def ssh_ctrl(ip, user, password,cmd):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect(hostname=ip, username=user, password=password, timeout=tout, compress = True,look_for_keys=False, allow_agent=False)
    except (socket.error,paramiko.AuthenticationException,paramiko.SSHException) as message:
        print "ERROR: SSH connection to "+ip+" failed: " +str(message)
        sys.exit(1)

    stdin, stdout, ssh_stderr = ssh.exec_command(cmd)
    out = stdout.read()
    stdin.flush()
    ssh.close()
    return out
person Mikhilesh Sekhar    schedule 11.04.2016