subprocess.popen, capturar stdout
Arnau Sanchez
arnau en ehas.org
Mar Oct 30 16:55:50 CET 2007
Oswaldo Hernández escribió:
> Para capturar la salida he probado:
> retorno=None
> while retorno is None:
> out, error = pr.communicate()
> retorno = pr.poll(50)
>
> Esto funciona, pero communicate() espera a que termine el proceso y da
> toda la salida de una vez.
Es lo que se espera de communicate():
communicate(input=None)
Interact with process: Send data to stdin. Read data from stdout
and stderr, until end-of-file is reached. Wait for process to terminate.
Salió algo parecido en este hilo:
http://listas.aditel.org/archivos/python-es/2007-September/018638.html
Todo lo que te diga en este mensaje está sólo probado en UNIX, no sé si
el comportamiento en Windows será el mismo. En fin, la solución más
simple que se me ocurre:
import subprocess
def get_popen(command):
sp = subprocess
return subprocess.Popen(command, stdout=sp.PIPE, stderr=sp.STDOUT)
command = "top -b"
popen = get_popen(command.split())
for line in popen.stdout:
print line,
popen.wait()
Fíjate que, al menos en UNIX, es necesario enviar a subprocess el
comando como lista (por eso hago el split()), no como cadena como hacías
en tu ejemplo.
Ahora bien, no siempre el comando a ejecutar hará un flush para cada
línea que escriba, y entonces nuestra situación no habrá mejorado: la
lectura en popen.stdout se quedará igualmente parada. Si te ocurre esto,
tienes que crear un generador que llame explícitamente al readline() del
descriptor hasta agotar los datos:
def readlines(fd):
while 1:
line = fd.readline()
if not line:
break
yield line
Si estás familiarizado con las itertools, esta función también puede
escribirse de forma más compacta, así:
import itertools
def readlines(fd):
genlines = (fd.readline() for _ in itertools.repeat(None))
return itertools.takewhile(bool, genlines)
Cualquiera de las dos se usaría de este modo:
for line in readlines(popen.stdout):
print line,
Prueba y nos dices si algo de esto te funciona.
arnau
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es