example español python subprocess

python - español - Recibiendo mensaje de progreso de un subproceso



subprocess python español (3)

Quiero comenzar un programa que necesita varios minutos para completar. Durante este tiempo, quiero leer el mensaje de progreso del programa (que está impreso en la salida estándar). El problema es que no puedo encontrar una manera de leer su salida durante su ejecución.

La única función que encontré para leer la salida de un programa es Popen.communicate() , pero este método espera hasta que finalice el proceso. Por lo tanto, es imposible obtener el progreso y hacerlo visible para el usuario en un formato especial.

¿Es posible hacerlo de otra manera?

Cuando ejecuto el proceso con subprocess.popen con mi script, veo el resultado del programa en la pantalla. ¿Es posible ocultarlo? (Ubuntu 10.10, terminal normal)


Ciertamente es posible: mi paquete python-gnupg hace exactamente esto, generando gpg (Gnu Privacy Guard) bajo un subproceso. En el caso general, debe especificar subprocess.PIPE para el subproceso stdout y stderr; luego cree dos subprocesos separados que lean el subproceso stdout y stderr a donde desee.

En el caso de python-gnupg , los mensajes de estado de gpg se leen y se ejecutan mientras el proceso de gpg se está ejecutando (sin esperar hasta que finalice).

Básicamente, el pseudocódigo es

process = subprocess.Popen(..., stdout=subprocess.PIPE, stderr=subprocess.PIPE) stderr = process.stderr rr = threading.Thread(target=response_reader_func, args=(process.stderr,)) rr.setDaemon(True) rr.start() dr = threading.Thread(target=data_reader_func, args=(process.stdout,)) dr.setDaemon(True) dr.start() dr.join() rr.join() process.wait()

Las funciones del lector suelen ser métodos de una clase adjunta que hacen lo correcto en función de lo que están leyendo (en su caso, actualizando la información de progreso de alguna manera).


Lo más simple es llamar a Popen con el argumento de palabra clave stdout=subprocess.PIPE .

p = subprocess.Popen(["ls"], stdout=subprocess.PIPE) while True: line = p.stdout.readline() if not line: break print line

Para ver esto en acción, aquí hay dos scripts de muestra. python superprint.py ambos en el mismo directorio y ejecuta python superprint.py

printandwait.py:

import time import sys print 10 sys.stdout.flush() time.sleep(10) print 20 sys.stdout.flush()

superprint.py:

import subprocess import sys p = subprocess.Popen(["python printandwait.py"], shell=True, stdout=subprocess.PIPE) while True: print "Looping" line = p.stdout.readline() if not line: break print line.strip() sys.stdout.flush()


Puede hacer una encuesta sobre el estado de su subproceso y mantener las líneas de salida.

p = subprocess.Popen(''ls;sleep 10'', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) rc = p.poll() while rc != 0: while True: line = p.stdout.readline() if not line: break print line rc = p.poll() assert rc == 0