2013-12-08 5 views
5

Senden einer komplexen cmd Zeichenfolge aus einem vollständigen Dateipfad zu einer ausführbaren Datei, die mehrere Flags, Argumente, Parameter, Ein- und Ausgänge scheint mich shell = True sonst subprocess.Popen setzen müssen ist nicht in der Lage, etwas Komplexeres als nur einen einfachen Pfad zur ausführbaren Datei zu verstehen (ohne Leerzeichen in einem Dateipfad).Pythons Subprozess.Popen mit Shell = True. Warten Sie, bis es abgeschlossen ist

In meinem Beispiel habe ich eine ziemlich lange cmd:

cmd = " '/Application/MyApp.app/Contents/MacOS/my_executable' '/Path/to/input/files' -some -flags -here -could -be -a -lot '/full/path/to/output/files' " 

Einreichen dieses cmd zu subprocess.Popen "Ergebnissen zu einem Fehler, der auf etwas über den Weg beschwert und nicht in der Lage, es zu finden.

So anstelle von:

proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

check_call scheint Arbeiten recht gut:

proc = subprocess.check_call(cmd, shell=True) 

Interessant, erst nach Schal zu Wahren

shell=True 

die subprocess.check_call arbeitet mit einem mitgelieferten cmd gesetzt.

Der Nebeneffekt ist, dass der Rest des Codes läuft scheint ohne zu warten subprocess.check_call (cmd, shell = True) zuerst zu beenden.

Der Code ist so konzipiert, dass der Rest der Ausführung von einem Ergebnis von subprocess.check_call(cmd, shell=True) abhängig ist.

Ich frage mich, ob es sowieso gibt, um die Ausführung des Codes zu erzwingen zu warten, bis subprocess.check_call (Cmd, Shell = True) abgeschlossen ist. Danke im Voraus!

+0

Haben Sie versucht, 'cmd' in eine Liste umzuwandeln, wenn Sie mit' shell = False' und 'subprocess.Popen' laufen? Sie können dazu die 'shlex.split()' -Funktion verwenden, wie im Beispiel-Code in der [Dokumentation des Popen-Konstruktors] (http://docs.python.org/2/library/subprocess.html#) Popen-Konstruktor). – miikkas

Antwort

2

Wie @mikkas empfiehlt es nur als list verwenden hier ist ein funktionierendes Beispiel:

mainProcess = subprocess.Popen(['python', pyfile, param1, param2], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

# get the return value from the method 
communicateRes = mainProcess.communicate() 

stdOutValue, stdErrValue = communicateRes 

Du python.exe pyfile param1 param2

Durch Sie können mit communicate() Aufruf Holen Sie sich die stdout und stderr als Tuple

Sie Python-Methode verwenden können split() Ihre Zeichenfolge in eine Liste beispielsweise aufzuspalten:

cmd = "python.exe myfile.py arg1 arg2" 

cmd.split(" ") 

Ausgang:

['python.exe', 'myfile.py', 'arg1', 'arg2'] 
+2

Vermeiden Sie 'cmd.split ('')', da es keine Anführungszeichen verarbeiten kann. Verwenden Sie stattdessen "shlex.split", das die Syntax für die Befehle der Shell kennt und damit Dinge wie "program" ein einzelnes Argument mit Anführungszeichen "'' wie erwartet behandelt. – Bakuriu

+0

Nice wusste das nicht –

1

Ich denke, die check_call-Funktion sollte warten, bis der Befehl beendet ist.

Lesen Sie die Dokumentation hier http://docs.python.org/2/library/subprocess.html

+0

Ich muss den Stand des laufenden Prozesses lesen. Lässt subprocess.check_call sein stdout lesen? Wenn ja, bitte erläutern Sie, wie dies zu erreichen ist. – alphanumeric

+1

Warum versuchen Sie nicht stattdessen subprocess.check_output? – Aaron

-1

prüfen Anruf wartet nicht. Du musst so einen Prozess machen.wait() und überprüfe den Rückgabecode explizit, um die gewünschte Funktion zu erhalten.

Process = subprocess.Popen('%s' %command_string,stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 
      Process.wait() 
      if Process1.returncode!=0: 
        print Process1.returncode 
        sendMail() 
        return 
      else: 
        sendMail()