2009-07-26 21 views
20

Estoy tratando de leer un proceso que produce resultados largos y lentos. Sin embargo, quiero ver su salida cuando se produce. Pero el uso de algo como lo siguiente parece ser amortiguar la salida del comando, por lo que terminan siendo las líneas de salida a la vez:Lectura sin búfer del proceso mediante el subproceso en Python

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=0) 
    for line in p.stdout: 
     print line 

Estoy tratando esto en MacOS 10.5

+0

duplicado: http://stackoverflow.com/questions/874815/how-do-i-get-real-time-information-back-from -a-subprocess-popen-in-python-2-5, http://stackoverflow.com/questions/527197/intercepting-stdout-of-a-subprocess-while-it-is-running –

Respuesta

28

El iterador archivo está haciendo algunos almacenamiento en memoria intermedia interna on its own. Prueba esto:

line = p.stdout.readline() 
while line: 
    print line 
    line = p.stdout.readline() 
+0

Funciona muy bien. ¡Gracias! – Abhi

+0

Gracias, me salvaste un poco de cabello. – haridsv

6

Por lo general, cada programa va a hacer más de amortiguación en sus canales de entrada y/o salida de lo que aparentas que desear ... a menos que sea engañado en la creencia de dicho canal en realidad es un terminal!

Para ese propósito de "engañar por una buena causa", use pexpect - funciona bien en una Mac (la vida es más difícil en Windows, aunque hay soluciones que podrían ayudar incluso allí), afortunadamente no necesitamos piense en ésos cuando usa una Mac en su lugar).

3

Este fue en realidad un error que está fijado en Python 2.6: http://bugs.python.org/issue3907

+4

En python 2.7 'para la línea en p.stdout' aún retrasa su salida, mientras que' para la línea en iter (p.stdout.readline, b '') 'funciona como se esperaba (produce líneas tan pronto como están disponibles). – jfs

+0

Lo sentimos, 2.x no usará la biblioteca io nueva de forma predeterminada, como dice el último comentario en el informe de errores; Tendría que hacer algo como 'for line in io.open (p.stdin.fileno())'. – Ari

+1

@Ari: ¿Debería ser 'para la línea en io.open (p.stdout.fileno())'? –

Cuestiones relacionadas