Better Command-line Scripts with Optparse

Posted on February 20, 2007

I am a stubborn command-line junky. ViM is still my preferred editor and I still keep a copy of lynx on my workstation. I tend to write scripts to perform ever more complex or repetitive tasks. Normally I simply use a combination of bash and PERL where appropriate. However, I’ve found that I was always parsing the argument array or too limited by the shell. Not one for repetitiveness, I found an elegant solution in Python…

Enter optparse. This handy module takes away the pain of parsing command-line arguments for your scripts. It has a simple interface and clean, standard output. While your grimoire of scripts may never be seen by the uninitiated; you’ll quickly appreciate being able to come back to a script and not have to search through its source to remember what options it takes.

The first step is to import the module and instantiate an object:

#!/usr/bin/env python

import optparse

def main():
    p = optparse.OptionParser(version="%prog: 1.0.0")

The OptionParser object can take a few arguments to set things up. In the above example we defined a version number for our program. Basically it’s the string the script will echo when the user passes the “-v” flag to our script. See the module documentation for more information.

The next step is to start adding those command-line arguments via the “add_option()” method.

#!/usr/bin/env python

import optparse

def main():
    p = optparse.OptionParser(version="%prog: 1.0.0")
    p.add_option("--search", "-s", dest="userString", help="Search string")
    p.add_option("--force", "-f", action="store_true", dest="force", help="Force recursive search without prompt")

The first two arguments of add_option() are required. The first is the long-form and the second is the short; pretty standard fare for command-line scripts in the UNIX world. Following those arguments is a list of parameters; the full list of which is too long to get into here but makes for good reading. In this example we use some very common ones – “dest” which defines a variable name to store argument values in; “help” which contains a string that describes what the given flag/argument does; and “action” which stores a boolean value (instead of a string) we can test against.

In order to test our variables, we must make a call to the “parse_args()” method.

#!/usr/bin/env python

import optparse

def main():
    p = optparse.OptionParser(version="%prog: 1.0.0")
    p.add_option("--search", "-s", dest="userString", help="Search string")
    p.add_option("--force", "-f", action="store_true", dest="force", help="Force recursive search without prompt")

    options, arguments = p.parse_args()

def search():
    if options.force:
        ... do stuff ...

We assign the output of parse_args() to some variables and then we can use those values throughout our script. It does recognize types, so booleans will be true booleans. Nice and easy, no?

The benefit of using optparse is not only less code for more functionality; but you automatically get a “-h” flag which lists your script’s arguments and any accompanying help strings. If you do happen to pass along some of your voodoo scripts, it will certainly help keep your users from inundating you with pesky questions and give you more time to code more magic. It’s also good practice to remind yourself what a particular script does when you find yourself going back through your tome and dusting off some old goodies.