Python-subprocess-Interaktion, warum mein Prozess arbeiten Popen.kommunizieren, aber nicht Popen.stdout.read()?
Ich versuche, die Kommunikation mit einem command-line-chat-bot mit Python mithilfe der subprocess
Modul. (http://howie.sourceforge.net/verwenden Sie die kompilierte win32-binary, ich habe meine Gründe!)
Dies funktioniert:
proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE)
output = proc.communicate()
Aber Popen.communicate
wartet, bis der Prozess zu kündigen (und es sendet EOF?), Ich möchte in der Lage sein, mit ihm zu interagieren. Die offensichtliche Lösung für dieses war zu Lesen stdout
/schreiben stdin
etwa so:
Dies nicht funktioniert:
proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE)
while True: print proc.stdout.readline()
(Beachten Sie, dass ich bin eigentlich mit komplexeren code basiert auf http://code.activestate.com/recipes/440554/ aber das Problem ist das gleiche.)
Das problem ist, der zweite Ansatz arbeitet perfekt für die Kommunikation mit cmd, aber wenn ich den chatbot, nichts. Also meine Frage ist, wie unterscheidet sich dies bei der Erfassung von output, um über Popen.kommunizieren()?
d.h. ich kann mit dem zweiten Ansatz, um die Befehlszeile verwenden, wie normal, bis ich den chatbot, an welcher Stelle ich mehr erhalten Ausgabe. Mit dem ersten Ansatz korrekt zeigt die ersten paar Zeilen der Ausgabe von bot, aber lässt mich nicht in der Lage, mit ihm zu interagieren.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einen großen Unterschied zwischen den beiden ist, dass die Kommunikation() schließt stdin nach dem senden der Daten. Ich weiß nicht, über Ihren speziellen Fall, aber in vielen Fällen bedeutet dies, dass, wenn ein Prozess auf das Ende der Benutzer-Eingabe, er werde es, wenn die Kommunikation() verwendet wird, und es auch nie bekommen wirst, wenn der code blocks read() oder readline().
Versuchen, indem Popen.stdin.close() zuerst und sehen, ob es wirkt sich auf Ihre Fall.
Popen.communicate
hat, obwohl jetzt habe ich das Problem, dass ich in der Lage sein zu sprechen zu halten, um es...subprocess
wenn Sie möchten, eine bidirektionale Kommunikation mit einem Prozess.Wenn Sie interagieren wollen mit dem Programm nach dem Absenden des EOF, anstatt
Popen.stdin.close()
können Sie manuell senden Sie die command-line End-Of-File-Zeichen, das hat den gleichen Effekt, lässt aber stdin öffnen.In Python diese Zeichen der escape-Sequenz ist
'\x1a'
.^Z
als EOF-marker. Auf vielen anderen Systemen ist dies in der Regel^D
(\x04
) statt, es kann jedoch problemlos geändert werden und sollte nicht als verlässlich angesehen werden und definitiv nie irgendwo hardcoded.