Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Command Line Interfaces in Python
Adding the capability of processing Python command-line arguments provides a user-friendly interface to your text-based command line program. It’s similar to what a graphical user interface is for a visual application that’s manipulated by graphical elements or widgets.
Python exposes a mechanism to capture and extract your Python command-line arguments. These values can be used to modify the behavior of a program. For example, if your program processes data read from a file, then you can pass the name of the file to your program, rather than hard-coding the value in your source code.
By the end of this tutorial, you’ll know:
- The origins of Python command-line arguments
- The underlying support for Python command-line arguments
- The standards guiding the design of a command-line interface
- The basics to manually customize and handle Python command-line arguments
- The libraries available in Python to ease the development of a complex command-line interface
If you want a user-friendly way to supply Python command-line arguments to your program without importing a dedicated library, or if you want to better understand the common basis for the existing libraries that are dedicated to building the Python command-line interface, then keep on reading!
Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level.
The Command-Line Interface
A command-line interface (CLI) provides a way for a user to interact with a program running in a text-based shell interpreter. Some examples of shell interpreters are Bash on Linux or Command Prompt on Windows. A command-line interface is enabled by the shell interpreter that exposes a command prompt. It can be characterized by the following elements:
- A command or program
- Zero or more command line arguments
- An output representing the result of the command
- Textual documentation referred to as usage or help
Not every command-line interface may provide all these elements, but this list isn’t exhaustive, either. The complexity of the command line ranges from the ability to pass a single argument, to numerous arguments and options, much like a Domain Specific Language. For example, some programs may launch web documentation from the command line or start an interactive shell interpreter like Python.
The two following examples with the Python command illustrates the description of a command-line interface:
$ python -c "print('Real Python')"
Real Python
In this first example, the Python interpreter takes option -c for command, which says to execute the Python command-line arguments following the option -c as a Python program.
Another example shows how to invoke Python with -h to display the help:
$ python -h
usage: python3 [option] ... [-c cmd | -m mod | file | -] [arg] ...
Options and arguments (and corresponding environment variables):
-b : issue warnings about str(bytes_instance), str(bytearray_instance)
and comparing bytes/bytearray with str. (-bb: issue errors)
[ ... complete help text not shown ... ]
Try this out in your terminal to see the complete help documentation.
The C Legacy
Python command-line arguments directly inherit from the C programming language. As Guido Van Rossum wrote in An Introduction to Python for Unix/C Programmers in 1993, C had a strong influence on Python. Guido mentions the definitions of literals, identifiers, operators, and statements like break, continue, or return. The use of Python command-line arguments is also strongly influenced by the C language.
To illustrate the similarities, consider the following C program:
1// main.c
2#include <stdio.h>
3
4int main(int argc, char *argv[]) {
5 printf("Arguments count: %d\n", argc);
6 for (int i = 0; i < argc; i++) {
7 printf("Argument %6d: %s\n", i, argv[i]);
8 }
9 return 0;
10}
Line 4 defines main(), which is the entry point of a C program. Take good note of the parameters:
argcis an integer representing the number of arguments of the program.argvis an array of pointers to characters containing the name of the program in the first element of the array, followed by the arguments of the program, if any, in the remaining elements of the array.
You can compile the code above on Linux with gcc -o main main.c, then execute with ./main to obtain the following:
$ gcc -o main main.c
$ ./main
Arguments count: 1
Argument 0: ./main
Unless explicitly expressed at the command line with the option -o, a.out is the default name of the executable generated by the gcc compiler. It stands for assembler output and is reminiscent of the executables that were generated on older UNIX systems. Observe that the name of the executable ./main is the sole argument.
Let’s spice up this example by passing a few Python command-line arguments to the same program:
$ ./main Python Command Line Arguments
Arguments count: 5
Argument 0: ./main
Argument 1: Python
Argument 2: Command
Argument 3: Line
Argument 4: Arguments
The output shows that the number of arguments is 5, and the list of arguments includes the name of the program, main, followed by each word of the phrase "Python Command Line Arguments", which you passed at the command line.
Note: argc stands for argument count, while argv stands for argument vector. To learn more, check out A Little C Primer/C Command Line Arguments.
The compilation of main.c assumes that you used a Linux or a Mac OS system. On Windows, you can also compile this C program with one of the following options:
- Windows Subsystem for Linux (WSL): It’s available in a few Linux distributions, like Ubuntu, OpenSUSE, and Debian, among others. You can install it from the Microsoft Store.
- Windows Build Tools: This includes the Windows command line build tools, the Microsoft C/C++ compiler
cl.exe, and a compiler front end namedclang.exefor C/C++. - Microsoft Visual Studio: This is the main Microsoft integrated development environment (IDE). To learn more about IDEs that can be used for both Python and C on various operating systems, including Windows, check out Python IDEs and Code Editors (Guide).
- mingw-64 project: This supports the GCC compiler on Windows.
If you’ve installed Microsoft Visual Studio or the Windows Build Tools, then you can compile main.c as follows:
C:/>cl main.c
You’ll obtain an executable named main.exe that you can start with:
C:/>main
Arguments count: 1
Argument 0: main
You could implement a Python program, main.py, that’s equivalent to the C program, main.c, you saw above:
# main.py
import sys
if __name__ == "__main__":
print(f"Arguments count: {len(sys.argv)}")
for i, arg in enumerate(sys.argv):
print(f"Argument {i:>6}: {arg}")
You don’t see an argc variable like in the C code example. It doesn’t exist in Python because sys.argv is sufficient. You can parse the Python command-line arguments in sys.argv without having to know the length of the list, and you can call the built-in len() if the number of arguments is needed by your program.
Also, note that enumerate(), when applied to an iterable, returns an enumerate object that can emit pairs associating the index of an element in sys.arg to its corresponding value. This allows looping through the content of sys.argv without having to maintain a counter for the index in the list.
Execute main.py as follows:
$ python main.py Python Command Line Arguments
Arguments count: 5
Argument 0: main.py
Argument 1: Python
Argument 2: Command
Argument 3: Line
Argument 4: Arguments
sys.argv contains the same information as in the C program:
- The name of the program
main.pyis the first item of the list. - The arguments
Python,Command,Line, andArgumentsare the remaining elements in the list.
With this short introduction into a few arcane aspects of the C language, you’re now armed with some valuable knowledge to further grasp Python command-line arguments.
Two Utilities From the Unix World
To use Python command-line arguments in this tutorial, you’ll implement some partial features of two utilities from the Unix ecosystem:
You’ll gain some familiarity with these Unix tools in the following sections.
sha1sum
sha1sum calculates SHA-1 hashes, and it’s often used to verify the integrity of files. For a given input, a hash function always returns the same value. Any minor changes in the input will result in a different hash value. Before you use the utility with concrete parameters, you may try to display the help:
$ sha1sum --help
Usage: sha1sum [OPTION]... [FILE]...
Print or check SHA1 (160-bit) checksums.
With no FILE, or when FILE is -, read standard input.
-b, --binary read in binary mode
-c, --check read SHA1 sums from the FILEs and check them
--tag create a BSD-style checksum
-t, --text read in text mode (default)
-z, --zero end each output line with NUL, not newline,
and disable file name escaping
[ ... complete help text not shown ... ]
Displaying the help of a command line program is a common feature exposed in the command-line interface.
To calculate the SHA-1 hash value of the content of a file, you proceed as follows:
$ sha1sum main.c
125a0f900ff6f164752600550879cbfabb098bc3 main.c
The result shows the SHA-1 hash value as the first field and the name of the file as the second field. The command can take more than one file as arguments:
$ sha1sum main.c main.py
125a0f900ff6f164752600550879cbfabb098bc3 main.c
d84372fc77a90336b6bb7c5e959bcb1b24c608b4 main.py
Thanks to the wildcards expansion feature of the Unix terminal, it’s also possible to provide Python command-line arguments with wildcard characters. One such a character is the asterisk or star (*):
$ sha1sum main.*
3f6d5274d6317d580e2ffc1bf52beee0d94bf078 main.c
f41259ea5835446536d2e71e566075c1c1bfc111 main.py
The shell converts main.* to main.c and main.py, which are the two files matching the pattern main.* in the current directory, and passes them to sha1sum. The program calculates the SHA1 hash of each of the files in the argument list. You’ll see that, on Windows, the behavior is different. Windows has no wildcard expansion, so the program may have to accommodate for that. Your implementation may need to expand wildcards internally.
Without any argument, sha1sum reads from the standard input. You can feed data to the program by typing characters on the keyboard. The input may incorporate any characters, including the carriage return Enter. To terminate the input, you must signal the end of file with Enter, followed by the sequence Ctrl+D:
1$ sha1sum
2Real
3Python
487263a73c98af453d68ee4aab61576b331f8d9d6 -
You first enter the name of the program, sha1sum, followed by Enter, and then Real and Python, each also followed by Enter. To close the input stream, you type Ctrl+D. The result is the value of the SHA1 hash generated for the text Real\nPython\n. The name of the file is -. This is a convention to indicate the standard input. The hash value is the same when you execute the following commands:
$ python -c "print('Real\nPython\n', end='')" | sha1sum
87263a73c98af453d68ee4aab61576b331f8d9d6 -
$ python -c "print('Real\nPython')" | sha1sum
87263a73c98af453d68ee4aab61576b331f8d9d6 -
$ printf "Real\nPython\n" | sha1sum
87263a73c98af453d68ee4aab61576b331f8d9d6 -
Up next, you’ll read a short description of seq.
seq
seq generates a sequence of numbers. In its most basic form, like generating the sequence from 1 to 5, you can execute the following:
$ seq 5
1
2
3
4
5
To get an overview of the possibilities exposed by seq, you can display the help at the command line:
$ seq --help
Usage: seq [OPTION]... LAST
or: seq [OPTION]... FIRST LAST
or: seq [OPTION]... FIRST INCREMENT LAST
Print numbers from FIRST to LAST, in steps of INCREMENT.
Mandatory arguments to long options are mandatory for short options too.
-f, --format=FORMAT use printf style floating-point FORMAT
-s, --separator=STRING use STRING to separate numbers (default: \n)
-w, --equal-width equalize width by padding with leading zeroes
--help display this help and exit
--version output version information and exit
[ ... complete help text not shown ... ]
For this tutorial, you’ll write a few simplified variants of sha1sum and seq. In each example, you’ll learn a different facet or combination of features about Python command-line arguments.
On Mac OS and Linux, sha1sum and seq should come pre-installed, though the features and the help information may sometimes differ slightly between systems or distributions. If you’re using Windows 10, then the most convenient method is to run sha1sum and seq in a Linux environment installed on the WSL. If you don’t have access to a terminal exposing the standard Unix utilities, then you may have access to online terminals:
- Create a free account on PythonAnywhere and start a Bash Console.
- Create a temporary Bash terminal on repl.it.
These are two examples, and you may find others.
The sys.argv Array
Before exploring some accepted conventions and discovering how to handle Python command-line arguments, you need to know that the underlying support for all Python command-line arguments is provided by sys.argv. The examples in the following sections show you how to handle the Python command-line arguments stored in sys.argv and to overcome typical issues that occur when you try to access them. You’ll learn:
- How to access the content of
sys.argv - How to mitigate the side effects of the global nature of
sys.argv - How to process whitespaces in Python command-line arguments
- How to handle errors while accessing Python command-line arguments
- How to ingest the original format of the Python command-line arguments passed by bytes
Let’s get started!
Displaying Arguments
The sys module exposes an array named argv that includes the following:
argv[0]contains the name of the current Python program.argv[1:], the rest of the list, contains any and all Python command-line arguments passed to the program.
The following example demonstrates the content of sys.argv:
1# argv.py
2import sys
3
4print(f"Name of the script : {sys.argv[0]=}")
5print(f"Arguments of the script : {sys.argv[1:]=}")
Here’s how this code works:
- Line 2 imports the internal Python module
sys. - Line 4 extracts the name of the program by accessing the first element of the list
sys.argv. - Line 5 displays the Python command-line arguments by fetching all the remaining elements of the list
sys.argv.
Note: The f-string syntax used in argv.py leverages the new debugging specifier in Python 3.8. To read more about this new f-string feature and others, check out Cool New Features in Python 3.8.
If your Python version is less than 3.8, then simply remove the equals sign (=) in both f-strings to allow the program to execute successfully. The output will only display the value of the variables, not their names.
Execute the script argv.py above with a list of arbitrary arguments as follows:
$ python argv.py un deux trois quatre
Name of the script : sys.argv[0]='argv.py'
Arguments of the script : sys.argv[1:]=['un', 'deux', 'trois', 'quatre']
The output confirms that the content of sys.argv[0] is the Python script argv.py, and that the remaining elements of the sys.argv list contains the arguments of the script, ['un', 'deux', 'trois', 'quatre'].
To summarize, sys.argv contains all the argv.py Python command-line arguments. When the Python interpreter executes a Python program, it parses the command line and populates sys.argv with the arguments.
Reversing the First Argument
Now that you have enough background on sys.argv, you’re going to operate on arguments passed at the command line. The example reverse.py reverses the first argument passed at the command line:
1# reverse.py
2
3import sys
4
5arg = sys.argv[1]
6print(arg[::-1])
In reverse.py the process to reverse the first argument is performed with the following steps:
- Line 5 fetches the first argument of the program stored at index
1ofsys.argv. Remember that the program name is stored at index0ofsys.argv. - Line 6 prints the reversed string.
args[::-1]is a Pythonic way to use a slice operation to reverse a list.
You execute the script as follows:
$ python reverse.py "Real Python"
nohtyP laeR
As expected, reverse.py operates on "Real Python" and reverses the only argument to output "nohtyP laeR". Note that surrounding the multi-word string "Real Python" with quotes ensures that the interpreter handles it as a unique argument, instead of two arguments. You’ll delve into argument separators in a later section.
Mutating sys.argv
sys.argv is globally available to your running Python program. All modules imported during the execution of the process have direct access to sys.argv. This global access might be convenient, but sys.argv isn’t immutable. You may want to implement a more reliable mechanism to expose program arguments to different modules in your Python program, especially in a complex program with multiple files.
Observe what happens if you tamper with sys.argv:
# argv_pop.py
import sys
print(sys.argv)
sys.argv.pop()
print(sys.argv)
You invoke