Read standard input in Python

Use input for prompts, stream lines from sys.stdin, or accept files and pipes with fileinput without accidentally consuming input twice.

Best practices
Python programming and application logging

Use input() for a single prompted line, iterate over sys.stdin for a stream of lines, and use fileinput when a command should accept either filenames or standard input.

Read one line

name = input("Name: ")
print(f"Hello, {name}")

input() returns a string without the trailing newline and raises EOFError when it reaches end of input without reading data. It also works with redirected input, although a prompt is usually undesirable in a pipeline.

Convert numeric input explicitly with int() or float(), catching ValueError when the input is invalid. For passwords, use getpass.getpass() rather than a normal prompt; it attempts to disable echo and warns if the environment cannot support that mode.

Stream lines from a pipe

Save this as filter.py:

import sys

for line in sys.stdin:
    if "ERROR" in line:
        print(line, end="")

Run it with:

cat access.log | python3 filter.py | sort | uniq -c

This processes complete lines as they arrive. It can still wait for a newline or EOF, and upstream buffering can delay delivery.

If the input is small and you need it all at once, use this alternative:

import sys

data = sys.stdin.read()

Do not call read() and then expect a following loop to see the same data: read() has already consumed it. An unbounded read waits for EOF, such as when the producer closes its pipe. In a POSIX terminal, Ctrl-D can signal EOF; behavior varies by terminal and platform.

Accept filenames as well as stdin

import fileinput

with fileinput.input(encoding="utf-8") as lines:
    for line in lines:
        print(line, end="")

With no file arguments, fileinput.input() reads stdin. With arguments, it reads those files in order; a filename of - denotes stdin. The encoding argument is available in Python 3.10 and later.

Detect a terminal

import sys

if sys.stdin.isatty():
    print("Input is connected to a terminal", file=sys.stderr)

isatty() reports whether the stream is connected to a terminal. A false result does not prove that a pipe contains data or that reading will not block; redirected files and other stream types also return false.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting