example español python process subprocess stdout popen

python - español - Interceptación estándar de un subproceso mientras se está ejecutando



subprocess python 3 example (2)

Si este es mi subproceso:

import time, sys for i in range(200): sys.stdout.write( ''reading %i/n''%i ) time.sleep(.02)

Y esta es la secuencia de comandos que controla y modifica la salida del subproceso:

import subprocess, time, sys print ''starting'' proc = subprocess.Popen( ''c:/test_apps/testcr.py'', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE ) print ''process created'' while True: #next_line = proc.communicate()[0] next_line = proc.stdout.readline() if next_line == '''' and proc.poll() != None: break sys.stdout.write(next_line) sys.stdout.flush() print ''done''

¿Por qué readline y communicate esperan hasta que el proceso finalice? ¿Hay una manera simple de pasar (y modificar) el subproceso ''stdout en tiempo real?

Por cierto, he visto this , pero no necesito las funciones de registro (y no me he molestado en comprenderlo en gran parte).

Estoy en Windows XP.


Como Charles ya mencionó, el problema es amortiguar. Me encontré con un problema similar al escribir algunos módulos para SNMPd, y lo resolví reemplazando stdout con una versión de limpieza automática.

Usé el siguiente código, inspirado por algunas publicaciones en ActiveState:

class FlushFile(object): """Write-only flushing wrapper for file-type objects.""" def __init__(self, f): self.f = f def write(self, x): self.f.write(x) self.f.flush() # Replace stdout with an automatically flushing version sys.stdout = FlushFile(sys.__stdout__)


La salida del proceso está protegida. En más sistemas operativos UNIXy (o Cygwin), el módulo pexpect está disponible, que recita todos los conjuros necesarios para evitar problemas relacionados con el almacenamiento en búfer. Sin embargo, estos conjuros requieren un módulo pty de trabajo, que no está disponible en las versiones de Win32 Python nativas (no cygwin).

En el caso de ejemplo donde usted controla el subproceso, puede hacer que lo llame sys.stdout.flush() cuando sea necesario, pero para los subprocesos arbitrarios, esa opción no está disponible.

Ver también la pregunta "¿Por qué no usar una tubería (popen ())?" en las preguntas frecuentes pexpect