stdin, stdout and stderr

sys · Essentials · 9 min

Programs that use the standard streams correctly can be combined with pipes and redirection like any Unix tool.

Every process starts with three open standard streams, which sys exposes as text file objects:

  • sys.stdin: input, from the keyboard or from a pipe (cat data.txt | python script.py).
  • sys.stdout: normal output; print writes here by default.
  • sys.stderr: errors, warnings and progress messages.

Keep the two outputs separate. When a user runs python report.py > out.csv, only stdout goes to the file; messages on stderr still reach the terminal and don't corrupt the data. Write to stderr with print("warning: ...", file=sys.stderr).

Reading input:

  • for line in sys.stdin: processes input line by line without loading it all; each line keeps its \n, so call line.rstrip("\n").
  • sys.stdin.read() reads everything at once.
  • input() reads one line from stdin and strips the newline.

Buffering matters: stdout is line-buffered in a terminal but block-buffered when redirected to a file or pipe, so output may appear late. Use print(..., flush=True) or sys.stdout.flush() for progress output; stderr is always line-buffered. sys.stdout.reconfigure(line_buffering=True) changes the mode.

For binary data use the underlying buffers, sys.stdin.buffer and sys.stdout.buffer, which read and write bytes.

Example

import subprocess
import sys

script = '''
import sys
total = 0
for line in sys.stdin:
    line = line.rstrip("\\n")
    if not line.isdigit():
        print(f"skipping {line!r}", file=sys.stderr)
        continue
    total += int(line)
print(total)
'''
r = subprocess.run([sys.executable, "-c", script], input="4\nx\n6\n",
                   capture_output=True, text=True)
print(r.stdout.strip())   # 10
print(r.stderr.strip())   # skipping 'x'

Remember

  • stdout is for results, stderr for messages, so redirection stays clean
  • for line in sys.stdin streams input; lines keep their newline
  • Redirected stdout is block-buffered; flush progress output explicitly

Watch out for

  • Printing progress messages to stdout in a tool whose output is piped into another program.

Check yourself

  1. A user runs python export.py > data.csv. Where should export.py write 'processed 500 rows' so data.csv stays clean?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/library/sys.html#sys.stdout