Seite 1 von 1

subprocess => offenen stdout lesen

Verfasst: Samstag 20. März 2021, 10:12
von werwurm01
Hallo,
ich bin neu hier und versuche mich gerade in Python.
Als Projekt möchte ich eine SSH Session zu Geräten aufbauen und Befehle ausführen.
Da Paramiko nicht funktioniert (siehe viewtopic.php?f=3&t=51439), habe ich mir einen anderen Weg gesucht.
Nun arbeite ich mit subprocess.Popen um eine PLINK.exe zu starten und eine Commandline SSH Session zu etablieren.
Das klappt generell. Ich kann mich Verbinden, Befehle ausführen und alles läuft.

Code: Alles auswählen

cmd = 'plink -ssh {} -P {} -l {} -pw {} -batch'.format(server, port, user, password)
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, encoding='utf8', bufsize=1)
p.stdin.write(ls -l\n')
Leider sollen die Befehle auf spezielle Ausgaben basieren, weshalb ich die Ausgabe in eine PIPE umleite und auslesen kann. Und hier liegt das Problem.
Wie kann ich den stdout lesen, wenn dieser noch offen ist und auch noch offen sein soll?

Code: Alles auswählen

print(p.stdout.readlines())
print(p.stdout.read())

funktionieren nicht, weil logischerweise auf das EOF gewartet wird, welches es noch nicht gibt.

Code: Alles auswählen

print(p.stdout.readline())

Damit bekomme ich eine Zeile angezeigt.
Normalerweise hat der Output immer mehrere Zeilen (Befehl und Ergebnis). Deshalb kann ich auch den readlines-Befehl wiederholen und es klappt.
Doch sobald ich eine Zeile zuviel Abfrage bliebt das Programm hängen, da auf eine Ausgabe gewartet wird.

Hatte an sowas gedacht, was leider nicht funktioniert

Code: Alles auswählen

out = ''
while True:
    line = p.stdout.read()
    if not line:
        break
    else:
        out += line
print("STDOUT >> " + out)
Hat da jemand eine Idee für mich?

Viele Grüße,
Marcus

Re: subprocess => offenen stdout lesen

Verfasst: Samstag 20. März 2021, 16:42
von __blackjack__
@werwurm01: Das sieht nach einem Fall für `pexpect` aus. Aber so etwas ist auch generell recht frickelig und nicht immer robust, weil man dafür ja wirklich alle möglichen Ausgaben von dem externen Programm kennen muss.