it-swarm.com.de

liefert die Ausgabe eines paramiko ssh exec_command fortlaufend

Ich führe ein langlebiges Python-Skript über ssh auf einem Remote-Computer mit paramiko aus. Funktioniert wie ein Zauber, bisher keine Probleme. 

Leider wird der stdout (bzw. der stderr) erst angezeigt, wenn das Skript beendet ist! Aufgrund der Ausführungszeit würde ich jedoch sehr bevorzugen, dass jede neue Zeile so ausgegeben wird, wie sie gedruckt wird und nicht danach. 

remote = paramiko.SSHClient()
remote.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
remote.connect("Host", username="uname", password="pwd")

# myScript produces continuous output, that I want to capture as it appears    
stdin, stdout, stderr = remote.exec_command("python myScript.py")
stdin.close()
for line in stdout.read().splitlines():
    print(line)

Wie kann das erreicht werden? Anmerkung: Natürlich könnte man die Ausgabe in eine Datei pipsen und diese Datei über eine andere SSH-Sitzung "weniger" machen, aber dies ist sehr hässlich und ich brauche eine sauberere, idealerweise Pythonic-Lösung :)

14

Wie in der Dokumentation von read ([size]) angegeben, wird, wenn Sie keine size angeben, bis EOF gelesen, was das Skript warten lässt, bis der Befehl endet, bevor Sie von read() zurückkehren und eine beliebige drucken Ausgabe.

Überprüfen Sie diese Antworten: Wie wird in Python bis EOF geschlungen? und Wie man ein "While nicht EOF" macht , um Beispiele zu erhalten, wie man das dateiähnliche Objekt erschöpft.

9
KurzedMetal

Ein minimales und vollständiges Arbeitsbeispiel für die Verwendung von diese Antwort (getestet in Python 3.6.1)

# run.py
from paramiko import SSHClient

ssh = SSHClient()
ssh.load_system_Host_keys()

ssh.connect('...')

print('started...')
stdin, stdout, stderr = ssh.exec_command('python -m example', get_pty=True)

for line in iter(stdout.readline, ""):
    print(line, end="")
print('finished.')

und

# example.py, at the server
import time

for x in range(10):
    print(x)
    time.sleep(2)

auf dem lokalen Rechner mit ausführen 

python -m run
7
Jorge Leitão

Ich war mit einem ähnlichen Problem konfrontiert. Ich konnte es lösen, indem ich paramiko mit get_pty = True fügte:

stdin, stdout, stderr = client.exec_command("/var/mylongscript.py", get_pty=True)
7
James Shrum