example español python linux subprocess popen

python - español - Cómo obtener salida del subproceso.Popen(). bloques proc.stdout.readline(), no se imprimen datos



subprocess python 3 popen (4)

Quiero que la salida ejecute Test_Pipe.py, traté de seguir el código en Linux pero no funcionó.

Test_Pipe.py

import time while True : print "Someting ..." time.sleep(.1)

Caller.py

import subprocess as subp import time proc = subp.Popen(["python", "Test_Pipe.py"], stdout=subp.PIPE, stdin=subp.PIPE) while True : data = proc.stdout.readline() #block / wait print data time.sleep(.1)

La línea proc.stdout.readline() se bloqueó, por lo que no se imprimen datos.


El fragmento de Nadia funciona, pero llamar a leer con un buffer de 1 byte es muy desaconsejado. La mejor manera de hacer esto sería establecer el descriptor de archivo stdout en nonblocking usando fcntl

fcntl.fcntl( proc.stdout.fileno(), fcntl.F_SETFL, fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK, )

y luego usar seleccionar para probar si los datos están listos

while proc.poll() == None: readx = select.select([proc.stdout.fileno()], [], [])[0] if readx: chunk = proc.stdout.read() print chunk

Ella tenía razón en que su problema debe ser diferente de lo que publicó porque Caller.py y Test_Pipe.py funcionan según lo previsto.


Obviamente puedes usar subprocess.communicate pero creo que estás buscando entrada y salida en tiempo real.

readline fue bloqueado porque el proceso probablemente esté esperando su entrada. Puedes leer carácter por personaje para superar esto como el siguiente:

import subprocess import sys process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) while True: out = process.stdout.read(1) if out == '''' and process.poll() != None: break if out != '''': sys.stdout.write(out) sys.stdout.flush()


Para evitar los muchos problemas que siempre pueden surgir con el almacenamiento en búfer para tareas como "obtener la salida del subproceso para el proceso principal en tiempo real", siempre recomiendo usar pexpect para todas las plataformas que no sean Windows, wexpect en Windows, en lugar de subprocess , cuando tales tareas son deseadas.


Test_Pipe.py almacena su stdout de forma predeterminada, por lo que proc en Caller.py no ve ningún resultado hasta que el búfer del niño esté lleno (si el tamaño del búfer es de 8 KB, tarda aproximadamente un minuto en llenar el búfer stdout de Test_Pipe.py ).

Para hacer que la salida esté sin búfer (línea de búfer para las secuencias de texto) puede pasar el indicador -u al script de Python secundario. Permite leer el subproceso ''salida línea por línea en'' tiempo real '':

import sys from subprocess import Popen, PIPE proc = Popen([sys.executable, "-u", "Test_Pipe.py"], stdout=PIPE, bufsize=1) for line in iter(proc.stdout.readline, b''''): print line, proc.communicate()

Vea los enlaces en Python: lea la entrada de transmisión por secuencias desde subprocess.communicate () sobre cómo resolver el problema del buffer de bloques para procesos secundarios que no sean de Python.