2011-09-12 15 views
12

puedo redirigir éxito mi salida a un archivo, sin embargo, esto parece sobrescribir los datos existentes en el archivo:anexar subproceso.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) 

eliminará la línea 'Hello' del archivo.

Supongo que una solución es almacenar el resultado en otro lugar como una cadena o algo así (no será demasiado largo), y anexarlo manualmente con outfile.write(thestring) - pero me preguntaba si me falta algo dentro del módulo que facilita esta.

Respuesta

12

Puede agregar la salida de subprocess.Popen a un archivo, y hago un uso diario de la misma. Así es como lo hago:

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) 

(por supuesto, esto es un ejemplo ficticio, no estoy usando subprocess para listar los archivos ...)

Por cierto, cualquier objeto con write() puede sustituir este elemento log, por lo que puede almacenar en búfer el resultado y hacer lo que quiera con él (escribir en un archivo, mostrar, etc.) dentro de este objeto similar a un archivo.

Nota: lo que puede inducir a error, es el hecho de que subprocess, por alguna razón que no entiendo, escribirá antes de lo que desea escribir. Por lo tanto, aquí está la manera de utilizar esto:

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) 

Así que la sugerencia es: no se olvide de flush la salida!

+0

Nota sobre el post anterior: después de algunos ensayos, parece que 'subprocess.Popen' necesita algo así como un archivo para sus argumentos' stdout' y 'stderr', por lo que darles un objeto personalizado con solo un método' write' no es suficiente. Lo intenté, pero se requiere una función 'fileno', y no soy lo suficientemente bueno para emular esto en una clase propia. –

+2

He estado intentando utilizar este método, pero he descubierto que por alguna razón, cada vez que ejecuto el proceso externo con un archivo que definitivamente he abierto para anexar, el resultado del proceso escribe desde el principio del archivo y sobrescribe cualquier información allí. Entonces, para usar esta solución, uno debe llamar a log.seek (0, os.SEEK_END) inmediatamente después de abrir el archivo. – Luke

0

¿Están realmente sobrescritos los datos en el archivo? En mi host Linux Tengo el siguiente comportamiento: 1) su ejecución de código en el directorio separado obtiene:

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

2) si añado outfile.flush() después outfile.write('Hello'), resultados es ligeramente diferente:

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

Pero el archivo de salida tiene Hello en ambos casos. Sin el flush() explícito, el buffer estándar de stdout se purgará cuando finalice el proceso de python. ¿Dónde está el problema?

0

Bueno el problema es que si quieres la cabecera para ser encabezado, entonces usted necesita para limpiar antes de que el resto de la salida se escribe en el archivo: D