2015-07-06 6 views
5

Ich habe eine ausführbare Datei, die Zeichenfolge akzeptiert und gibt eine andere Zeichenfolge aus. Jetzt muss ich eine Datei als Eingabe füttern und Ausgabe in eine andere Datei schreiben. Der Standardbefehl dafür lautet wie folgt executable_path <input> output. Jetzt wickle ich das in Python ein. Aber ich bekomme Fehler.Python Subprozess Aufruf mit größerem Vorzeichen (>) funktioniert nicht

cmd = [executable_path , '<', 'tmp/input.txt', '>', 
      'tmp/output.txt'] 
    p = subprocess.Popen(cmd) 
    p.communicate() 

invalid argument: <

Ich habe versucht Beitritt auch die cmd Argumente:

cmd = [executable_path, ' '.join(['<', 'tmp/input.txt', '>', 
     'tmp/output.txt'])] 

invalid argument: < tmp/input.txt > tmp/output.txt

den Befehl Passing als Zeichenfolge entweder nicht funktioniert hat. hier

p = subprocess.Popen(' '.join(cmd)) 

OSError: [Errno 2] No such file or directory

Was bin ich?

Antwort

3

subprocess.Popen() hat drei Parameter für eine einfache Umleitung: stdin, stdout und stderr. Standardmäßig speichert der Subprozess die Dateideskriptoren Ihrer Python-Instanz.

with open('tmp/input.txt', 'rb', 0) as in_stream, \ 
    open('tmp/output.txt', 'wb', 0) as out_stream: 
    subprocess.Popen([executable_path], stdin=in_stream, stdout=out_stream) 

macht dasselbe wie der Shell-Befehl executable_path <tmp/input.txt> tmp/output.txt.

Die Argumente zu open() sind der Dateiname, der Modus und die Pufferung. "rb" bedeutet "binäre Daten lesen", "wb" bedeutet "binäre Daten überschreiben", "ab" bedeutet "binäre Daten anhängen".

+0

Das klingt besser als das, was ich ursprünglich hatte. Ich bin zu dieser Lösung gewechselt. Vielen Dank. – CentAu

+1

Sie können wirklich jede Art von Datei-Deskriptor, z. Pipes und sogar TCP [Sockets] (https://docs.python.org/2/library/socket.html#socket.socket.fileno). – kay

+2

@ user292139: nicht verwandt: 1. Verwenden Sie '.communicate()' nicht, wenn Sie 'PIPE' verwenden. Sie könnten stattdessen 'subprocess.check_call ([ausführbarer_pfad], stdin = in_stream, stdout = out_stream)' verwenden. 2. Sie können hier keine TCP-Sockets verwenden, um die Ausgabe des Unterprozesses unter Windows umzuleiten. – jfs

6

Redirects (<, >) werden von Shell interpretiert. Sie müssen shell=True angeben, um sie zu verwenden.

cmd = [executable_path , '<', 'tmp/input.txt', '>', 'tmp/output.txt'] 
p = subprocess.Popen(cmd, shell=True) 
p.communicate() 
+3

Dies ist kein Job für 'shell = True'. Verwenden Sie stattdessen die Parameter 'stdin' und' stdout' von 'Popen()'. – kay