How to stream lines from stdout with subprocess
Use subprocess.Popen()
with bufsize=1
and text=True
, then you can interate over the lines with proc.stdout
.
I was writing a Python script that shells out to external tool which prints output line-by-line to stdout. I wanted my script to read those lines, and then do some follow-up work for each line.
I know several ways to run an external process and capture the stdout with the subprocess
module, but they’re all blocking – I have to wait for the entire process to complete. This is annoying and inefficient if the external tool is slow. Ideally I’d like to stream lines from the external tool; to start my follow-up work as soon as there’s a line available.
Today I discovered that if you start a process with subprocess.Popen()
, and you pass bufsize=1
and text=True
, then the stdout will be line-buffered. This allows you to iterate over lines as they’re written, rather than waiting for all of them.
Here’s an example:
import subprocess
args = ["yt-dlp", "--get-id", "https://www.youtube.com/watch?list=PLCbA9r6ecYWU6SVyvb32a0YHIzpr9jxnW"]
proc = subprocess.Popen(args, stdout=subprocess.PIPE, bufsize=1, text=True)
for line in proc.stdout:
print(line)
proc.poll()
print(proc.returncode)