example español python subprocess

español - ¿Puedes hacer una salida de subproceso python stdout y stderr como de costumbre, pero también capturar la salida como una cadena?



subprocess python español (3)

Cree dos lectores como el anterior, uno para stdout uno para stderr y comience cada uno en un nuevo hilo. Esto se adjuntaría a la lista aproximadamente en el mismo orden en que fueron generados por el proceso. Mantén dos listas separadas si quieres.

es decir,

p = subprocess.Popen(["the", "command"]) t1 = thread.start_new_thread(func,stdout) # create a function with the readers t2 = thread.start_new_thread(func,stderr) p.wait() # your logic here

Posible duplicado:
Envolver subproceso ''stdout / stderr

En esta pregunta , hanan-n preguntó si era posible tener un subproceso python que produzca salidas a la salida estándar mientras que también mantiene la salida en una cadena para su posterior procesamiento. La solución en este caso fue recorrer cada línea de salida e imprimirlas manualmente:

output = [] p = subprocess.Popen(["the", "command"], stdout=subprocess.PIPE) for line in iter(p.stdout.readline, ''''): print(line) output.append(line)

Sin embargo, esta solución no se generaliza en el caso de que desee hacer esto tanto para stdout como para stderr, a la vez que satisface lo siguiente:

  • la salida de stdout / stderr debe ir al proceso principal ''stdout / stderr respectivamente
  • la salida se debe hacer en tiempo real tanto como sea posible (pero solo necesito acceso a las cadenas al final)
  • el orden entre las líneas stdout y stderr no se debe cambiar (no estoy muy seguro de cómo funcionaría si el subproceso vacia sus cachés stdout y stderr a diferentes intervalos; supongamos por ahora que obtenemos todo en buenos trozos que contienen contenido completo ¿líneas?)

Revisé la documentación del subproceso , pero no pude encontrar nada que pudiera lograrlo. Lo más cercano que pude encontrar es agregar stderr=subprocess.stdout y usar la misma solución que la anterior, pero luego perdemos la distinción entre resultados regulares y errores. ¿Algunas ideas? Supongo que la solución, si la hay, implicará tener lecturas asíncronas en p.stdout y p.stderr .

Aquí hay un ejemplo de lo que me gustaría hacer:

p = subprocess.Popen(["the", "command"]) p.wait() # while p runs, the command''s stdout and stderr should behave as usual p_stdout = p.stdout.read() # unfortunately, this will return '''' unless you use subprocess.PIPE p_stderr = p.stderr.read() # ditto [do something with p_stdout and p_stderr]


Este ejemplo parece funcionar para mí:

# -*- Mode: Python -*- # vi:si:et:sw=4:sts=4:ts=4 import subprocess import sys import select p = subprocess.Popen(["find", "/proc"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = [] stderr = [] while True: reads = [p.stdout.fileno(), p.stderr.fileno()] ret = select.select(reads, [], []) for fd in ret[0]: if fd == p.stdout.fileno(): read = p.stdout.readline() sys.stdout.write(''stdout: '' + read) stdout.append(read) if fd == p.stderr.fileno(): read = p.stderr.readline() sys.stderr.write(''stderr: '' + read) stderr.append(read) if p.poll() != None: break print ''program ended'' print ''stdout:'', "".join(stdout) print ''stderr:'', "".join(stderr)

En general, cualquier situación en la que quiera hacer cosas con varios descriptores de archivos al mismo tiempo y no sepa cuál tendrá cosas para leer, debe usar select o algo equivalente (como un reactor retorcido).


Para imprimir en la consola y capturar en una cadena stdout / stderr de un subproceso de una manera portátil:

from StringIO import StringIO fout, ferr = StringIO(), StringIO() exitcode = teed_call(["the", "command"], stdout=fout, stderr=ferr) stdout = fout.getvalue() stderr = ferr.getvalue()

¿dónde se define teed_call() en el subproceso de Python para obtener la salida de los niños en el archivo y la terminal?

Podría usar cualquier objeto similar a un archivo .write() método .write() ).