Working with Command Line Arguments in Python
Command-line arguments allow a Python script to accept filenames, options and commands without editing source code. For a tiny throwaway script, sys.argv may be enough. For a reusable tool, argparse from the standard library offers help messages, typed values, option flags and subcommands with more predictable error handling.
A robust command-line interface also treats its inputs as untrusted. Validate paths and numeric ranges, avoid building shell commands from arguments, and do not place secret tokens in ordinary command-line parameters where process listings or shell histories may expose them.
sys.argv is a list of strings. The first item normally represents the script name or invocation path, so user-supplied values start at index one. Explicit length checks prevent IndexError.
import sys
if len(sys.argv) < 2:
print("Usage: script.py NAME")
else:
print(sys.argv[1])
ArgumentParser creates a help interface and reports many input errors automatically. It supports required positionals, optional flags and typed conversion.
import argparse
parser = argparse.ArgumentParser(description="Task demo")
parser.add_argument("name")
parser.add_argument("--count", type=int, default=1)
args = parser.parse_args()
print(args.name, args.count)
action=’store_true’ creates a flag that is false unless supplied. Prefer explicit flags to manually searching sys.argv for strings, because parsing libraries handle help output and unknown option errors consistently.
parser.add_argument("--verbose", action="store_true")
# parser.parse_args() returns a namespace with verbose
Type conversion alone does not prove that a value is acceptable. A timeout may need to be positive and a path may need to belong to an allowed directory. Reject invalid values before touching files or networks.
parser.add_argument("--timeout", type=float, default=3.0)
args = parser.parse_args()
if args.timeout <= 0:
parser.error("--timeout must be positive")
A CLI with distinct actions can use subparsers to organize required inputs. Keep operations narrow and document their effects.
parser = argparse.ArgumentParser()
sub = parser.add_subparsers(dest="command", required=True)
show = sub.add_parser("show")
show.add_argument("item")
args = parser.parse_args()
The standard-library getopt module supports traditional option parsing, but its interface is lower level. Third-party docopt-style parsers can express usage-driven interfaces yet require dependency review. For most new Python tools, argparse is a maintainable default.
import getopt
options, rest = getopt.getopt(["-v", "file.txt"], "v")
print(options, rest)
For file-oriented commands, use pathlib and explicit text encodings. Catch known exceptions such as FileNotFoundError and PermissionError, and return meaningful exit codes. Avoid broad except blocks that silently hide failures.
from pathlib import Path
path = Path("items.txt")
try:
print(path.read_text(encoding="utf-8"))
except FileNotFoundError:
print("File not found")
Do not concatenate user arguments into a shell command string. For authorized subprocess execution, pass a list of arguments with shell=False by default. Use protected configuration or credential stores for secrets rather than public process command lines.
import subprocess
subprocess.run(["python", "--version"], check=True)
# Avoid shell=True with untrusted text
Use sys.argv for understanding the mechanics, argparse for most maintained command-line tools, and carefully selected alternatives only when justified. A good CLI is discoverable, validates input, reports failures and protects paths and credentials.
