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

  • Mit Python, um eine Shell-Umgebung zu öffnen, führen Sie eine Befehls- und Exit-Umgebung aus
  • Vorteil der Liste über String in Unterprozess-Methoden
  • Running Shell-Befehl aus Python und Erfassung der Ausgabe
  • Verwenden von Python, um ausführbare Datei auszuführen und die Benutzereingabe auszufüllen
  • Schreiben von großen Datenmengen an stdin
  • Django + Apache + Windows WSGIDaemonProcess Alternative
  • Unterschied zwischen subprocess.Popen und os.system
  • Öffnen Sie Textdatei in Notepad ++ mit Subprocess.Popen
  • 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.