2017-04-16 1 views
2

Ich versuche, einen Python-Code zu implementieren, wo ich eine externe ausführbare Datei ausführen muss. Nach einigen Recherchen fand ich subprocess Modul und versuchte es. Wenn ich jedoch den Code ausführe, wird der Subprozess beendet und ein CompletedProcess Objekt zurückgegeben, was für mich nicht in Ordnung ist, da die .exe, mit der ich arbeite, ein kontinuierliches Programm ist, wo es Eingaben benötigt und Ausgaben generiert, bis es geschlossen wird. (Mein Programm sendet seine Eingänge und empfängt die Ausgänge.)Run kontinuierliche EXE-Datei mit Python

Dieser Code schlägt also fehl.

Er erfasst die erste Ausgabe des Programms in stdout, wird dann aber beendet, anstatt neue Eingaben zu erwarten.

Ich bin auch ein Problem mit der Terminologie hier mit, diese ausführbar ich verwende ist in der Lage Befehle ausgeführt wird, während noch in der Lage neue Befehle zu empfangen, dann ist dies asynchrone oder Non-Blocking genannt?

Zu meiner Frage, was ist der richtige Weg, dies zu behandeln? Es gibt viele Fragen in der Nähe von SO, aber ich konnte mir nicht sicher sein, welche mein Problem beantworteten oder es auf moderne Weise beantworteten (Es gibt sehr alte Fragen).

Es wäre subprocess Modul durchliefen einige Änderungen mit Python 3.6.1 https://docs.python.org/3/library/subprocess.html

So wäre es am besten erscheinen, wenn Sie die Lösung in der neuesten Art und Weise, oder zumindest vor, könnten die neuere Art und Weise zu erwähnen und wie es funktioniert.

Ich arbeite an 10 Windows Python 3.6.1

Edit1: Ich habe über subprocess.Popen kommen, das, was sein kann, ich brauche, aber ich bin noch zu entdecken, wie man es richtig verwendet wird.

Edit2: Das Modul pexpect scheint für diese Art von Problemen entwickelt zu werden, aber ich bin mir nicht sicher, ob dies meine Zeit viel einfacher zu machen. Irgendwelche Vorschläge geschätzt.

+0

Können diese "Eingänge" einfach in den Befehl für den Subprozessaufruf geschrieben werden? – JacobIRR

+0

@JacobIRR, Ja, verzeihen Sie mir nicht zu erwähnen, das ist eine Konsolenanwendung und erhält Eingaben von stdin direkt. Ich kann es direkt ausführen und die Eingaben testen, die ich an meiner Python-Anwendung anstelle von mir brauche. – Rockybilly

+0

Aber die Eingänge sind nicht vorgegeben, ich kann nicht alle Eingänge angeben, wenn ich das Programm am Anfang anrufe. – Rockybilly

Antwort

1

Aus der Dokumentation:

subprocess.run()

Führen Sie das von args beschrieben Befehl. Warten Sie, bis der Befehl abgeschlossen ist, und geben Sie dann eine CompletedProcess-Instanz zurück.

Da Ihr Subprozess endet nicht, nachdem es zunächst aufrufen, können Sie nicht run verwenden, sondern müssen Popen stattdessen verwenden.

Man könnte so etwas wie folgt verwenden:

import subprocess 
p = subprocess.Popen(exe_path, 
        stdin=subprocess.PIPE, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT) 
while p.poll() is None: 
    p.stdin.write(some_command) 
    p.stdin.flush() 
    out = p.stdout.readline() 

Aber beachten Sie, dass dies zu einem Stillstand in der documentation wie beschrieben führen kann:

Warnung Verwenden kommunizieren() statt .stdin .schreiben, .stdout.read oder .stderr.read, um Deadlocks zu vermeiden, da die anderen OS-Pipe-Puffer den untergeordneten Prozess auffüllen und blockieren.

Leider können Sie communicate nicht verwenden, da dies erfordern würde, dass Sie den Prozess mit allen Eingaben aufrufen. Ich würde es mit der obigen Version versuchen und sehen, ob die Puffer wirklich Probleme in Ihrer Anwendung verursachen.

+0

Danke für die Antwort, ich stieß auch darauf, bevor Sie die Antwort geschrieben, scheint die einzige einfache Lösung für mein Problem. Ich muss nur diese in einer Funktion einpacken. Ich würde jedoch mehr Wissen über diese Deadlock-Situation und darüber, wie sie vermieden werden kann, schätzen. – Rockybilly

+0

siehe [hier] (http://stackoverflow.com/questions/2381751/can-someone-explain-pipe-buffer-deadlock) für eine Erklärung des Deadlock-Problems. Die hier vorgeschlagene Lösung [http://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python) könnte helfen, Deadlocks zu vermeiden, indem ein separater Thread verwendet wird, der Daten liest der Puffer, um das Auffüllen zu verhindern. – Felix