Ich habe ein Programm, das mit dem Benutzer interagiert (fungiert wie eine Shell), und ich möchte es interaktiv mit Python Subprozessmodul ausführen. Das heißt, ich möchte die Möglichkeit, in stdin schreiben und sofort die Ausgabe von stdout erhalten. Ich habe viele Lösungen ausprobiert, die hier angeboten werden, aber keine von ihnen scheint für meine Bedürfnisse zu funktionieren.Interaktive Eingabe/Ausgabe mit Python
Der Code, den ich habe auf der Grundlage schriftlicher Running an interactive command from within python
import Queue
import threading
import subprocess
def enqueue_output(out, queue):
for line in iter(out.readline, b''):
queue.put(line)
out.close()
def getOutput(outQueue):
outStr = ''
try:
while True: #Adds output from the Queue until it is empty
outStr+=outQueue.get_nowait()
except Queue.Empty:
return outStr
p = subprocess.Popen("./a.out", stdin=subprocess.PIPE, stout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize = 1)
#p = subprocess.Popen("./a.out", stdin=subprocess.PIPE, stout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, universal_newlines=True)
outQueue = Queue()
errQueue = Queue()
outThread = Thread(target=enqueue_output, args=(p.stdout, outQueue))
errThread = Thread(target=enqueue_output, args=(p.stderr, errQueue))
outThread.daemon = True
errThread.daemon = True
outThread.start()
errThread.start()
p.stdin.write("1\n")
p.stdin.flush()
errors = getOutput(errQueue)
output = getOutput(outQueue)
p.stdin.write("5\n")
p.stdin.flush()
erros = getOutput(errQueue)
output = getOutput(outQueue)
Das Problem ist, dass die Warteschlange leer bleibt, als ob es keine Ausgabe. Nur wenn ich alle Eingaben, die das Programm ausführen und beenden muss, an stdin schreibe, bekomme ich die Ausgabe (was ich nicht will). Zum Beispiel wenn ich etwas mache wie:
p.stdin.write("1\n5\n")
errors = getOutput(errQueue)
output = getOutput(outQueue)
Gibt es eine Möglichkeit zu tun, was ich tun möchte?
EDIT: Das Skript wird auf einer Linux-Maschine ausgeführt. Ich änderte mein Skript und löschte die universal_newlines = True + setzte die bufsize auf 1 und flushed stdin sofort nach wrtie. Trotzdem bekomme ich keine Ausgabe.
Zweiter Versuch: Ich habe versucht, diese Lösung und es funktioniert für mich:
from subprocess import Popen, PIPE
fw = open("tmpout", "wb")
fr = open("tmpout", "r")
p = Popen("./a.out", stdin = PIPE, stdout = fw, stderr = fw, bufsize = 1)
p.stdin.write("1\n")
out = fr.read()
p.stdin.write("5\n")
out = fr.read()
fw.close()
fr.close()
Ich verstehe nicht genau, was Sie meinen. Was ich zuerst machen wollte, ist nur Teilausgabe zu lesen (eine Zeile) –
Ich habe dein Beispiel nicht verstanden. Was bedeutet diese Zeile: p = Popen ([sys.executable, "-u", '-c' 'für Zeile iner (Eingabe, "")): print ("a" * int (Zeile) * 10 * * 6) '], stdin = PIPE, stdout = PIPE, bufsize = 1) bedeuten? –
Sie haben recht, ich habe meine zweite Lösung bearbeitet, als ich sie benutzt habe. Das Problem war, dass wenn ich die Lösung zuerst ausprobiert habe, habe ich es auf dem Python-Interpreter ausprobiert (ich habe das Skript nicht geschrieben, sondern nur manuell getestet), so dass es funktionierte (aufgrund der menschlichen langsamen Reaktionszeit). Als ich versucht habe, das Skript zu schreiben, bin ich auf das Problem gestoßen, das Sie erwähnt haben, also habe ich die while-Schleife hinzugefügt, bis die Eingabe fertig ist. Ich bekomme tatsächlich die gesamte Ausgabe oder nichts (IOError Ausnahme), wird es hilfreich sein, wenn ich den a.out Quellcode hochlade (es ist ein C Programm)? –