Interaktive Eingabe / Ausgabe mit Python

Ich habe ein Programm, das mit dem Benutzer interagiert (wirkt wie eine Shell), und ich möchte es mit python-Subprozess-Modul interaktiv ausführen. Das heißt, ich möchte die Möglichkeit, an stdin zu schreiben und sofort die Ausgabe von stdout zu bekommen. Ich habe viele Lösungen hier angeboten, aber keiner von ihnen scheint für meine Bedürfnisse zu arbeiten.

Der Code, den ich geschrieben habe, basiert auf dem Ausführen eines interaktiven Befehls aus 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 gibt. Nur wenn ich schreibe, um alle Eingaben zu schreiben, die das Programm ausführen und beenden muss, dann bekomme ich die Ausgabe (was ich nicht will). Zum Beispiel wenn ich so etwas mache:

 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 läuft auf einem Linux-Rechner. Ich änderte mein Skript und löschte die universal_newlines = True + setze die Bufsize auf 1 und spuckte stdin sofort nach wrtie. Trotzdem bekomme ich keine Ausgabe.

Zweiter Versuch: Ich habe diese Lösung ausprobiert 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() 

  • Multiprocessing.Pool Laich neue childern nach terminate () auf Linux / Python2.7?
  • FFMPEG und Pythons Teilprozess
  • Modul-Subprozess hat kein Attribut 'STARTF_USESHOWWINDOW'
  • Python Sub Prozessaufruf mit Dateinamenvariable
  • Python, subprocess: startet neuen Prozess, wenn einer (in einer Gruppe) beendet hat
  • Python-Unterprozess: Rückruf, wenn cmd beendet wird
  • Delegieren Sie die Signalverarbeitung an einen Kinderprozess in Python
  • Wie kann ich das Dateizu werden?
  • One Solution collect form web for “Interaktive Eingabe / Ausgabe mit Python”

    Zwei Lösungen für dieses Thema unter Linux:

    Zuerst soll man eine Datei verwenden, um die Ausgabe zu schreiben und gleichzeitig zu lesen:

     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() 

    Zweitens, wie JF Sebastian angeboten hat, ist es, p.stdout und p.stderr pipes non-blocking mit fnctl-Modul zu machen:

     import os import fcntl from subprocess import Popen, PIPE def setNonBlocking(fd): """ Set the file description of the given file descriptor to non-blocking. """ flags = fcntl.fcntl(fd, fcntl.F_GETFL) flags = flags | os.O_NONBLOCK fcntl.fcntl(fd, fcntl.F_SETFL, flags) p = Popen("./a.out", stdin = PIPE, stdout = PIPE, stderr = PIPE, bufsize = 1) setNonBlocking(p.stdout) setNonBlocking(p.stderr) p.stdin.write("1\n") while True: try: out1 = p.stdout.read() except IOError: continue else: break out1 = p.stdout.read() p.stdin.write("5\n") while True: try: out2 = p.stdout.read() except IOError: continue else: break 
    Python ist die beste Programmiersprache der Welt.