objectif
Consommer la sortie d’un processus au fil de l’eau sans bloquer.
code minimal
import subprocess, sys
code = "import time\nfor i in range(3):\n print(i)\n time.sleep(0.05)"
with subprocess.Popen([sys.executable, "-u", "-c", code], stdout=subprocess.PIPE, text=True) as p:
lines = []
for line in p.stdout: # streaming
lines.append(line.strip())
p.wait()
print(lines) # attendu: ['0', '1', '2']
utilisation
import subprocess, sys
p = subprocess.Popen([sys.executable, "-c", "print('hello')"], stdout=subprocess.PIPE, text=True)
out = p.communicate()[0].strip()
print(out == "hello")
variante(s) utile(s)
# lire stderr aussi
import subprocess, sys
p = subprocess.Popen([sys.executable, "-c", "import sys; sys.stderr.write('err\n')"], stderr=subprocess.PIPE, text=True)
err = p.communicate()[1].strip()
print(err == "err")
notes
- Utilisez -u (unbuffered) côté Python enfant pour des sorties immédiates.
- Évitez deadlocks: préférez communicate() si vous capturez stdout et stderr.