Python Command Line Arguments Examples

Posted on in Categories , , last updated March 7, 2016

I am a new Python programming user. I am working on user-friendly command-line interfaces, and I want to pass input via the shell args as follows:

./myscript.py filename
./myscript.py in.file output.file
./myscript.py -i in.file -o output.file

How do I pass and parse command-line options and arguments using Python under Linux or Unix-like operating systems?

Python provides the following two options:

  1. The getopt module is a parser for command line options whose API is designed to be familiar to users of the C getopt() function.
  2. The argparse module makes it easy to write user-friendly command-line interfaces and I recommend this module for all users.

Understanding command line parameters


Most Unix and Linux commands can take different actions depending on the command line arguments supplied to the command.

What is a command line argument?

A command line argument is nothing but an argument sent to a program being called. A program can take any number of command line arguments. For example, type the following command:
cat /etc/passwd
cat is the name of an actual command and shell executed this command when you type command at shell prompt. The first word on the command line is:

  1. cat – name of the command to be executed.
  2. Everything else on command line is taken as arguments to this command.
  3. Total number of command line arguments passed to the ls command including command name itself are 2.

Consider the following example:
ls --sort=size foo.txt bar.txt
Where,

  1. ls : Command name.
  2. --sort=size foo.txt bar.txt : The arguments.
  3. 3 : The total number of arguments.

Try the following command and note down its command line arguments:

CommandCommand nameTotal number of argumentsArguments
lsls0None
ls /etc/resolv.confls1/etc/resolv.conf
grep --color root /etc/passwdgrep2–color, root, /etc/passwd

getopt module

The syntax is:

import sys
 
# get argument list using sys module
sys.argv

Examples

Use the following code to display the total number of arguments passed to the demo.py:

#!/usr/bin/python
# demo.py - CMD Args Demo By nixCraft
import sys
 
# Get the total number of args passed to the demo.py
total = len(sys.argv)
 
# Get the arguments list 
cmdargs = str(sys.argv)
 
# Print it
print ("The total numbers of args passed to the script: %d " % total)
print ("Args list: %s " % cmdargs)

Save and close the file. Run it as follows:
$ python demo.py input.txt output.txt
OR
$ chmod +x demo.py
$ ./demo.py input.txt output.txt

Sample outputs:

The total numbers of args passed to the script: 3 
Args list: ['demo.py', 'input.txt', 'output.txt'] 

Parsing command line arguments (options and arguments)

Edit the file demo.py and update it as follows:

#!/usr/bin/python
__author__ = 'nixCraft'
import sys
 
total = len(sys.argv)
cmdargs = str(sys.argv)
print ("The total numbers of args passed to the script: %d " % total)
print ("Args list: %s " % cmdargs)
# Pharsing args one by one 
print ("Script name: %s" % str(sys.argv[0]))
print ("First argument: %s" % str(sys.argv[1]))
print ("Second argument: %s" % str(sys.argv[2]))

Save and close the file. Run it as follows:
$ ./demo.py input.txt output.txt
Sample outputs:

The total numbers of args passed to the script: 3 
Args list: ['./demo.py', 'input.txt', 'output.txt'] 
Script name: ./demo.py
First argument: input.txt
Second argument: output.txt

Try to run the same program as follows:
$ ./demo.py -i input.txt -o output.txt
Sample outputs:

The total numbers of args passed to the script: 5 
Args list: ['./demo.py', '-i', 'input.txt', '-o', 'output.txt'] 
Script name: ./demo.py
First argument: -i
Second argument: input.txt

The script only printed first three arguments and skipped the rest. The output is not correct. Further, how do you separate the options such as -i or -o and arguments passed to each option such as input.txt or output.txt? You can fix this problem with the following code:

#!/usr/bin/python
__author__ = 'nixCraft'
import sys
 
total = len(sys.argv)
cmdargs = str(sys.argv)
print ("The total numbers of args passed to the script: %d " % total)
print ("Args list: %s " % cmdargs)
print ("Script name: %s" % str(sys.argv[0]))
for i in xrange(total):
    print ("Argument # %d : %s" % (i, str(sys.argv[i])))

Sample outputs:

$ ./demo.py -i input.txt -o output.txt
The total numbers of args passed to the script: 5 
Args list: ['./demo.py', '-i', 'input.txt', '-o', 'output.txt'] 
Script name: ./demo.py
Argument # 0 : ./demo.py
Argument # 1 : -i
Argument # 2 : input.txt
Argument # 3 : -o
Argument # 4 : output.txt

However, I do not recommend to use the for loop and phrase the argument method. It was included here for demonstration and historical purpose only. The correct and recommend Python syntax is as follows:

#!/usr/bin/python
__author__ = 'nixCraft'
import sys, getopt
# Store input and output file names
ifile=''
ofile=''
 
# Read command line args
myopts, args = getopt.getopt(sys.argv[1:],"i:o:")
 
###############################
# o == option
# a == argument passed to the o
###############################
for o, a in myopts:
    if o == '-i':
        ifile=a
    elif o == '-o':
        ofile=a
    else:
        print("Usage: %s -i input -o output" % sys.argv[0])
 
# Display input and output file name passed as the args
print ("Input file : %s and output file: %s" % (ifile,ofile) )

Run it as follows:

$ ./demo.py -i foo.txt -o bar.txt
Input file : foo.txt and output file: bar.txt
$ ./demo.py -o bar.txt -i foo.txt
Input file : foo.txt and output file: bar.txt
$ ./demo.py -o bar.txt 
Input file :  and output file: bar.txt
$ ./demo.py 
Input file :  and output file: 

Creating usage messages

The updated code is as follows:

#!/usr/bin/python
__author__ = 'vivek'
import sys, getopt
 
ifile=''
ofile=''
 
###############################
# o == option
# a == argument passed to the o
###############################
# Cache an error with try..except 
# Note: options is the string of option letters that the script wants to recognize, with 
# options that require an argument followed by a colon (':') i.e. -i fileName
#
try:
    myopts, args = getopt.getopt(sys.argv[1:],"i:o:")
except getopt.GetoptError as e:
    print (str(e))
    print("Usage: %s -i input -o output" % sys.argv[0])
    sys.exit(2)
 
for o, a in myopts:
    if o == '-i':
        ifile=a
    elif o == '-o':
        ofile=a
 
# Display input and output file name passed as the args
print ("Input file : %s and output file: %s" % (ifile,ofile) )

Run it as follows:

$ ./demo.py -i input.txt -o output.txt
Input file : input.txt and output file: output.txt
$ ./demo.py -i input.txt -o output.txt -z
option -z not recognized
$ ./demo.py -i input.txt -o
option -o requires argument
Usage: ./demo.py -i input -o output

Say hello to argparse module

The argparse module helps you to write the same logic with less code and more informative help and error messages. The syntax is:

WARNING! These examples requires Python version 2.7 and above.
import argparse
parser = argparse.ArgumentParser(description='ADD YOUR DESCRIPTION HERE')
parser.add_argument('-i','--input', help='Input file name',required=True)
args = parser.parse_args()
## do something with args

Examples

Create a file called demo1.py:

#!/usr/bin/python
import argparse
__author__ = 'nixCraft'
 
parser = argparse.ArgumentParser(description='This is a demo script by nixCraft.')
parser.add_argument('-i','--input', help='Input file name',required=True)
parser.add_argument('-o','--output',help='Output file name', required=True)
args = parser.parse_args()
 
## show values ##
print ("Input file: %s" % args.input )
print ("Output file: %s" % args.output )

Save and close the file. Run it as follows:

$ chmod +x demo1.py
$ ./demo1.py 
usage: demo1.py [-h] -i INPUT -o OUTPUT
demo1.py: error: argument -i/--input is required
$ ./demo1.py -h
usage: demo1.py [-h] -i INPUT -o OUTPUT
This is a demo script by nixCraft.
optional arguments: -h, --help show this help message and exit -i INPUT, --input INPUT Input file name -o OUTPUT, --output OUTPUT Output file name $ ./demo1.py -i input.txt -o output.txt Input file: input.txt Output file: output.txt $ ./demo1.py -i input.txt usage: demo1.py [-h] -i INPUT -o OUTPUT demo1.py: error: argument -o/--output is required $ ./demo1.py -i input.txt -o output.txt -z usage: demo1.py [-h] -i INPUT -o OUTPUT demo1.py: error: unrecognized arguments: -z $ ./demo1.py --input input.txt --output output.txt Input file: input.txt Output file: output.txt
References:
  1. Python argparse module and getopt module.

# Additional correction by Frank W; Editing by VG – log #

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on Twitter, Facebook, Google+.

18 comment

  1. Hey Vivik the genius! Always thanks for your awesome tutorials. :) By the way, which module do you prefer, getopt or argparse? I have used argparse before but its kinda long right? Now im comfortable for just the sys module but i would like to know your opinion so i can practice that module you prefer.

  2. HI,

    I am trying to pass command line arguments to my script which has a sentence, but the problem is, the words in sentence separated by spaces are considered as different arguments. is there a way to treat it as one argument?

    For example, if I am passing “Hello! This is my computer” as one argument, the script treats Hello! as argument 1, This as argument2 and so on. I want the script to treat the whole sentence as one argument.

    Thanks for Help
    Ananth

    1. Can you advise me how to run the following which is supposed to insert dummy lines in a srt (subtitle) file for Samsung TVs?:

      #! /usr/bin/python
      import sys;
      
      # Patching SRT files to make them readable on Samsung TVs
      # It basically inserts blank subtitles when silence should occur.
      
      seqNo=1
      
      try:
          subs = open(sys.argv[1])
      except:
          print "Please provide subtitle file to process"
          sys.exit(1)
          
      while True:
          srtSeqNo=subs.readline();
          try:
              begin,arrow,end=subs.readline().rstrip('\n\r').split(" ")
          except:
              break
          srtText = subs.readline();
          again = subs.readline();
          while len(again.strip('\n\r')) > 0:
              srtText = srtText + again
              again = subs.readline()
          print "%d\n%s --> %s\n%s" % (seqNo, begin, end, srtText)
      
          seqNo = seqNo + 1
          print "%d\n%s --> %s\n%s\n" % (seqNo, end, end, "   ")
          seqNo = seqNo + 1
      

      No matter what I try I get the line 12 “Please provide subtitle file to process” message.
      I am obviously not parsing the file name correctly. I am sure this is easy, but not knowing Python, I just can work it out. Also is it possible to create a Windows exe file from this so I don’t need to use the CMD line?
      Regards and thanks.

  3. Very good write up. Just getting my feet wet with Raspberry Pi/python and wanted to do some command line arguments and error checking. This article answered my questions perfectly and I like the logical approach for the presentation.
    Thanks

  4. thx. super useful!

    is there a way to pass arguments into a running script?

    im thinking of building a script that runs in the background and handles network inputs and outputs stuff passed as args into it.

  5. I am comparing two excel files and getting one output excel file. I want to give the paths to all three files as command line arguments.
    Can I give something like the following:
    test.py -i -o
    Thanks in advance

    1. You could add another argument in between for the second file.
      If using argparse:
      parser.add_argument(‘-e’,’–input_2′,help=’Second file’, required=True)

  6. Hi,
    Thats super useful.
    Also can anyone help me with these two :
    1.
    I would like to parse
    ./pythonscript.py -i input -a auth_type -o output
    if auth_type is NONE expect nothing
    if auth_type is 8021x expect user_id and password also to be passed as parameters like :
    ./python.py -i input -a 8021x user_name password -o output
    Is this possible ?

    2.
    For the same python script I would like to have different set of parameters

    ./pythonscript.py stop number
    ex: ./pythponscript.py stop 3

    Can anyone please help me with this.
    Thanks in advance:)

Leave a Comment