← retour aux snippets

subprocess: lire stdout en streaming (ligne par ligne)

Consommer la sortie d'un processus au fil de l'eau sans bloquer.

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.