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.