Monday, January 3, 2011

perl: Parsing command line parameters with Getopt::Long

Getopt::Long is a very powerful module which gives you a great deal of control over command line arguments.
To use this module, you specify the type of command line parameters you expect to receive using the function GetOptions(). GetOptions() will return a true value if the command line arguments could be processed successfully; otherwise it will print an appropriate error message to STDERR and return false.
By default, the arguments are not case sensitive, could start with either a single (-) or a double (--) dash and may be abbreviated to uniqueness.


Here are some usage examples:
-- arguments with no values (example: "program --debug")
GetOptions('debug' => \$variable);
$variable will be set to 1 if parameter '--debug' is defined, otherwise $variable will be left untouched

-- arguments with a single value (example: "program --color red")

You append symbols to the name of the parameter to specify the type of value (string, integer or float) and whether the value is mandatory or optional.
GetOptions('color=s' => \$variable); # a string value required
GetOptions('color:s' => \$variable); # a string value is optional
GetOptions('color=i' => \$variable); # an integer value is required
GetOptions('color:i' => \$variable); # an integer value is optional
GetOptions('color=f' => \$variable); # a float value is required
GetOptions('color:f' => \$variable); # a float value is optional

$variable will hold the value of the parameter. If the value is optional and is not provided in the command line, the value of $variable will be an empty string in case of strings and 0 (zero) in case of integers and floats.

-- arguments with multiple values (example: "program --dir /tmp --dir /usr/lib")

The syntax is similar to the one used to specify a single value, the only difference is that you must specify a reference to an array instead of a reference to a scalar as the destination:
GetOptions('dir=s' => \@variable);
In this case, the array @variable will store all the values defined in all ocurrences of the parameter 'dir'.
-- arguments with multiple names (example: "program --help" or "program -?")
Useful in case you want to allow alternate names for the same option (for example: --dir, --path, --location). You specify all the alternate names together, separated by the vertical bar ('|') character.
GetOptions('dir|path|location=s' => \$variable);
The first name specified is the primary name; all the other are called aliases.

-- handling unexpected arguments

Use the special option '<>' to specify a function that will be called when an unexpected parameter is found.
GetOptions('dir=s' => \$variable, '<>' => \&function);
'function()' will receive as parameters all the unexpected command line arguments passed to the program.


-- Complete example

#!/usr/bin/perl
use Getopt::Long;

my ($help, @url, $size);

#-- prints usage if no command line parameters are passed or there is an unknown
#   parameter or help option is passed
usage() if ( ! GetOptions('help|?' => \$help, 'url=s' => \@url, 'size=i' => \$size)
         or @ARGV < 1 or defined $help );

sub usage
{
  print "Unknown option: @_\n" if ( @_ );
  print "usage: program [--url URL] [--size SIZE] [--help|-?]\n";
  exit;
}

No comments: