Je veux la sortie de Exécuter Test_Pipe.py, j'ai essayé de suivre le code sous Linux mais cela n'a pas fonctionné.
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 ligne proc.stdout.readline()
a été bloquée, donc aucune donnée ne s'imprime.
Vous pouvez évidemment utiliser subprocess.communicate mais je pense que vous recherchez une entrée et une sortie en temps réel.
readline a été bloquée car le processus attend probablement votre entrée. Vous pouvez lire caractère par caractère pour surmonter ce problème comme suit:
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()
L'extrait de Nadia fonctionne, mais appeler read avec un tampon de 1 octet est fortement déconseillé. La meilleure façon de procéder serait de définir le descripteur de fichier stdout sur nonblocking en utilisant fcntl
fcntl.fcntl(
proc.stdout.fileno(),
fcntl.F_SETFL,
fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK,
)
puis en utilisant select pour tester si les données sont prêtes
while proc.poll() == None:
readx = select.select([proc.stdout.fileno()], [], [])[0]
if readx:
chunk = proc.stdout.read()
print chunk
Elle avait raison en ce que votre problème doit être différent de ce que vous avez publié en tant que Caller.py et Test_Pipe.py fonctionnent comme prévu.
Test_Pipe.py
Met en mémoire tampon sa sortie standard par défaut afin que proc
dans Caller.py
Ne voit aucune sortie tant que le tampon de l'enfant n'est pas plein (si la taille du tampon est de 8 Ko, cela prend environ une minute pour remplir le tampon stdout de Test_Pipe.py
).
Pour rendre la sortie non tamponnée (mise en mémoire tampon pour les flux de texte), vous pouvez passer indicateur -u
à l'enfant Python. Il permet de lire le sous-processus 'sortie ligne par ligne en "temps réel":
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()
Voir les liens dans Python: lire les entrées de streaming de subprocess.communicate () sur la façon de résoudre le problème de mise en mémoire tampon des blocs pour les processus enfants non Python.
Pour éviter les nombreux problèmes qui peuvent toujours survenir avec la mise en mémoire tampon pour des tâches telles que "obtenir la sortie du sous-processus vers le processus principal en temps réel", je recommande toujours d'utiliser pexpect pour toutes les plates-formes non Windows, - wexpect sous Windows, au lieu de subprocess
, lorsque de telles tâches sont souhaitées.