Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Command-Line Streams and Exit Status in Python

Read command-line arguments, handle standard input and output streams, and return meaningful process exit statuses with Python’s sys module.

Levels: Intermediate ~22 min read

Intermediate

A command-line program has a small interface with the environment that starts it: it receives argument tokens, may read text from standard input, writes normal output and diagnostics to different streams, and finishes with an exit status. The sys module exposes these process-facing pieces. This lesson covers that boundary; argparse remains the better starting point for a structured command-line interface, and subprocess covers launching a separate child program.

Inspect the arguments your program receives

sys.argv is a list of strings supplied when the Python program starts. Item 0 is the script name (or another launch-specific value); sys.argv[1:] contains the arguments intended for your program. Tokens are not automatically converted or validated. For real options, defaults, help, and validation, let argparse own the interface instead of growing a fragile manual parser.

Interactive Runnable example
Edit

Ready to run.

Use standard input for piped text

sys.stdin is a text stream, like a file object. Use input() for one prompted response, but iterate over sys.stdin when a program should accept multiple lines from a pipe or redirected file. Each line normally includes its trailing newline; writing transformed lines with sys.stdout.write() preserves that newline without adding another one. The same processing function can accept any file-like text stream. This runnable example uses io.StringIO for repeatable sample input; a real command-line program can pass sys.stdin to the function instead.

Interactive Runnable example
Edit

Ready to run.

Keep normal output and diagnostics separate

Write results intended for a person or another program to sys.stdout. Write warnings and error messages to sys.stderr, often with print(..., file=sys.stderr). Separating these streams lets a caller redirect or pipe the result without accidentally treating a diagnostic as data. Both are text streams and may be redirected by a test runner or application, so library code should not assume they are always real terminal streams.

Interactive Runnable example
Edit

Ready to run.

Return a meaningful exit status

An exit status is a small signal to the shell, automation, or a parent process. Conventionally, 0 means success and a nonzero value means that the requested work did not complete successfully. Have a main() function return the status, and keep its decision-making testable. Do not use a nonzero status merely to report a harmless warning.

Interactive Runnable example
Edit

Ready to run.

Use SystemExit at the program boundary

At the script entry point, raise SystemExit(main()) to turn main()’s return value into the process exit status. sys.exit(code) does the same by raising SystemExit; it is not an immediate low-level termination call, so normal finally-block cleanup still runs. Passing a string prints a message to standard error and exits with status 1. Avoid catching BaseException broadly, which can intercept SystemExit and KeyboardInterrupt.

Interactive Runnable example
Edit

Ready to run.

Quick Check

Quick check

Which part of sys.argv contains the arguments intended for the program rather than the launch entry?

import sys
print(sys.argv[1:])

Quick check

Where should a command write a diagnostic that should not be mixed into normal output?

import sys
print("Record skipped", file=sys.stderr)

Quick check

Which stream is designed for reading multiple lines piped into a command?

from io import StringIO

source = StringIO("foxipa\npython\n")
print(sum(1 for _ in source))

Quick check

What does sys.exit(2) do in an ordinary script when the exception is not caught?

import sys
try:
    sys.exit(2)
except SystemExit as request:
    print(request.code)

Quick check

What is a good design for a command that needs validation, help, and named options?

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("count", type=int)
args = parser.parse_args(["3"])
print(args.count)
Was this page helpful?

Mark this learning resource complete to track your learning progress.