Pregunta

Si este es mi subproceso:

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

Y este es el guión controlar y modificar 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é se readline y communicate esperando hasta que el proceso ha terminado de correr? ¿Hay una manera simple para ser aprobada (y modificar) el subproceso stdout en tiempo real?

Por cierto, he visto esta , pero no necesito las funciones de registro (y no te has molestado entender gran parte de ella).

Estoy en Windows XP.

¿Fue útil?

Solución

Como Charles ya se ha mencionado, el problema es el almacenamiento en búfer. Me encontré a un problema similar al escribir algunos módulos para SNMPD, y lo resolvió mediante la sustitución de la salida estándar con una versión de auto-lavado.

I utilizado el código siguiente, inspirado por algunos puestos 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__)

Otros consejos

salida de proceso está tamponada. En más sistemas operativos UNIXy (o Cygwin), el pexpect módulo está disponible, que recita todo lo necesario conjuros para evitar problemas relacionados con tampón. Sin embargo, estos conjuros requieren un trabajo Pty módulo , que no está disponible en nativo (no cygwin) Win32 Python construye.

En el caso de ejemplo donde el control de la sub-proceso, sólo puede tener que llamar sys.stdout.flush() cuando sea necesario -. Pero para subprocesos arbitrarias, esa opción no está disponible

la pregunta "¿Por qué no utilizar un tubo (popen ())? " en el FAQ pexpect.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top