2011-09-12 6 views
12

posso reindirizzare con successo il mio output in un file, tuttavia questo sembra sovrascrivere i dati esistenti del file:append subprocess.Popen output to file?

import subprocess 
outfile = open('test','w') #same with "w" or "a" as opening mode 
outfile.write('Hello') 
subprocess.Popen('ls',stdout=outfile) 

rimuoverà la linea 'Hello' dal file.

Credo che una soluzione è quella di memorizzare l'output altrove come una stringa o qualcosa (non sarà troppo lungo), e aggiungere manualmente con outfile.write(thestring) - ma mi chiedevo se mi manca qualcosa all'interno del modulo che facilita Questo.

risposta

12

È possibile aggiungere l'output di subprocess.Popen a un file e utilizzarlo quotidianamente. Ecco come lo faccio:

log = open('some file.txt', 'a') # so that data written to it will be appended 
c = subprocess.Popen(['dir', '/p'], stdout=log, stderr=log, shell=True) 

(ovviamente, questo è un esempio fittizio, non sto usando subprocess per elencare i file ...)

Tra l'altro, qualsiasi oggetto con write() può sostituire questo elemento log, in modo da poter bufferizzare l'output e fare tutto ciò che volete con esso (scrivere su file, visualizzare, ecc) all'interno di questo oggetto simile a file.

Nota: ciò che può essere fuorviante, è il fatto che subprocess, per qualche ragione che non capisco, scriverà prima ciò che si desidera scrivere. Quindi, ecco il modo di usare questo:

log = open('some file.txt', 'a') 
log.write('some text, as header of the file\n') 
log.flush() # <-- here's something not to forget! 
c = subprocess.Popen(['dir', '/p'], stdout=log, stderr=log, shell=True) 

Quindi il suggerimento è: non dimenticare di flush l'uscita!

+0

Nota sul post di cui sopra: dopo alcune prove, sembra che 'subprocess.Popen' ha bisogno di qualcosa di veramente come un file per i suoi' stdout' e 'stderr'arguments, quindi dare a loro un oggetto personalizzato con solo un metodo' write' non è sufficiente. Ho provato, ma è necessaria una funzione 'fileno', e non sono abbastanza bravo da emularlo su una mia classe. –

+2

Ho tentato di utilizzare questo metodo ma ho scoperto che per qualche motivo, ogni volta che eseguo il processo esterno con un file che ho definitivamente aperto per l'aggiunta, l'output del processo scrive dall'inizio del file e sovrascrive qualsiasi informazione lì. Quindi, per poter utilizzare questa soluzione, è necessario chiamare log.seek (0, os.SEEK_END) subito dopo aver aperto il file. – Luke

0

I dati nel file sono davvero sovrascritti? Sul mio host Linux Ho il seguente comportamento: 1) il tuo esecuzione di codice nella directory separata ottiene:

$ cat test 
test 
test.py 
test.py~ 
Hello 

2) se aggiungo outfile.flush() dopo outfile.write('Hello'), risultati è leggermente diverso:

$ cat test 
Hello 
test 
test.py 
test.py~ 

Ma il file di output ha Hello in entrambi i casi. Senza esplicito flush(), il buffer stdout di chiamata verrà svuotato al termine del processo python. Dov'è il problema?

0

Ebbene il problema è che se si desidera che l'intestazione sia intestazione, allora avete bisogno di lavare prima del resto l'output viene scritto nel file: D