home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


15.1. Parsing Program Arguments

Problem

You want to let users change your program's behavior by giving options on the command line. For instance, you want to allow the user to control the level of output that your program produces with a -v (verbose) option.

Solution

Use the standard Getopt::Std module to permit single-character options:

use Getopt::Std;

# -v ARG, -D ARG, -o ARG, sets $opt_v, $opt_D, $opt_o
getopt("vDo");              
# -v ARG, -D ARG, -o ARG, sets $args{v}, $args{D}, $args{o}
getopt("vDo", \%args);

getopts("vDo:");         # -v, -D, -o ARG, sets $opt_v, $opt_D, $opt_o
getopts("vDo:", \%args); # -v, -D, -o ARG, sets $args{v}, $args{D}, $args{o}

Or, use the standard Getopt::Long module to permit named arguments:

use Getopt::Long;

GetOptions( "verbose"  => \$verbose,     # --verbose
            "Debug"    => \$debug,       # --Debug
            "output=s" => \$output );    # --output=string or --output=string

Discussion

Most traditional programs like ls and rm take single-character options (also known as flags or switches), such as -l and -r . In the case of ls -l and rm -r , the argument is Boolean: either it is present or it isn't. Contrast this with gcc -o compiledfile source.c , where compiledfile is a value associated with the option -o . We can combine Boolean options into a single option in any order. For example:

% rm -r -f /tmp/testdir

Another way of saying this is:

% rm -rf /tmp/testdir

The Getopt::Std module, part of the standard Perl distribution, parses these types of traditional options. Its getopt function takes a single string of characters, each corresponding to an option that takes a value, parses the command-line arguments stored in @ARGV , and sets a global variable for each option. For example, the value for the -D option will be stored in $opt_D . All options parsed though getopt are value options, not Boolean options.

Getopt::Std also provides the getopts function, which lets you specify whether each option is Boolean or takes a value. Arguments that take a value, like the -o option to gcc , are indicated by a : , as in this code:

use Getopt::Std;
getopts("o:");
if ($opt_o) {
    print "Writing output to $opt_o";
}

Both getopt and getopts can take a second argument, a reference to a hash. If present, option values are stored in $hash{X} instead of $opt_X :

use Getopt::Std;

%option = ();
getopts("Do:", \%option);

if ($option{D}) {
    print "Debugging mode enabled.\n";
}

 # if not set, set output to "-".  opening "-" for writing
 # means STDOUT
 $option{o} = "-" unless defined $option{o};
                             
print "Writing output to file $option{o}\n" unless $option{o} eq "-";
open(STDOUT, "> $option{o}")
     or die "Can't open $option{o} for output: $!\n";

You can specify some programs' options using full words instead of single characters. These options are (usually) indicated with two dashes instead of one:

% gnutar --extract --file latest.tar

The value for the - -file option could also be given with an equals sign:

% gnutar --extract --file=latest.tar

The Getopt::Long module's GetOptions function parses this style of options. It takes a hash whose keys are options and values are references to scalar variables:

use Getopt::Long;

GetOptions( "extract" => \$extract,
            "file=s"  => \$file );

if ($extract) {
    print "I'm extracting.\n";
}

die "I wish I had a file" unless defined $file;
print "Working on the file $file\n";

If a key in the hash is just an option name, it's a Boolean option. The corresponding variable will be set to false if the option wasn't given, or to 1 if it was. Getopt::Long provides fancier options than just the Boolean and value of Getopt::Std. Here's what the option specifier can look like:

Specifier

Value?

Comment

option

No

Given as - - option or not at all

option!

No

May be given as - - option or - - nooption

option=s

Yes

Mandatory string parameter: - - option = somestring

option:s

Yes

Optional string parameter: - - option or - - option = somestring

option=i

Yes

Mandatory integer parameter: - - option = 35

option:i

Yes

Optional integer parameter: - - option or - - option = 35

option=f

Yes

Mandatory floating point parameter: - - option = 3.141

option:f

Yes

Optional floating point parameter: - - option or - - option = 3.141

See Also

The documentation for the standard Getopt::Long and Getopt::Std modules; examples of argument parsing by hand can be found in Recipe 1.5 , Recipe 1.17 , Recipe 6.22 , Recipe 7.7 , Recipe 8.19 , and Recipe 15.12


Previous: 15.0. Introduction Perl Cookbook Next: 15.2. Testing Whether a Program Is Running Interactively
15.0. Introduction Book Index 15.2. Testing Whether a Program Is Running Interactively