2015-07-06 12 views
5

Ho un eseguibile che accetta la stringa e restituisce un'altra stringa. Ora ho bisogno di alimentare un file come input e scrivere l'output in un altro file. Il comando standard è simile al seguente executable_path <input> output. Ora lo avvolgo in python. Ma ottengo errori.Chiamata di sottoprocesso Python con segno maggiore (>) non funzionante

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

invalid argument: <

Ho provato anche unendo gli argomenti cmd:

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

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

Passando il comando come stringa non ha funzionato neanche.

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

OSError: [Errno 2] No such file or directory

Che cosa mi manca qui?

risposta

3

subprocess.Popen() ha tre parametri per una facile reindirizzamento: stdin, stdout e stderr. Di default il sottoprocesso conserva i descrittori di file della tua istanza Python.

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) 

fa lo stesso del comando shell executable_path <tmp/input.txt> tmp/output.txt.

Gli argomenti su open() sono nomefile, modalità e buffering. "rb" significa "leggi dati binari", "wb" significa "(sopra) scrive dati binari", "ab" significa "aggiungi dati binari".

+0

Sembra più pulito di quello che avevo in origine. Sono passato a questa soluzione. Grazie. – CentAu

+1

È possibile utilizzare qualsiasi tipo di descrittore di file, ad es. pipe, e anche TCP [socket] (https://docs.python.org/2/library/socket.html#socket.socket.fileno). – kay

+2

@ user292139: non correlato: 1. non utilizzare '.communicate()' a meno che non si usi 'PIPE'. Potresti usare 'subprocess.check_call ([executable_path], stdin = in_stream, stdout = out_stream)'. 2. Non è possibile utilizzare i socket TCP qui, per reindirizzare l'output dei sottoprocessi su Windows. – jfs

6

I reindirizzamenti (<, >) sono interpretati dalla shell. È necessario specificare shell=True per utilizzarli.

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

Questo non è un lavoro per 'shell = True'. Usa invece i parametri 'stdin' e' stdout' di 'Popen()'. – kay

Problemi correlati