Using Getopt::Long: More Command Line Options in Perl

In the last article, we took a look at command line options and how we could read them in Perl using the Getopt::Std module. For many simple applications, that article covers all that you need to make use of command line options. When you need more command line options, you can make use of the Getopt::Long module, which is the subject of this article.

The Getopt::Std module allows you to read and respond to short options, that can either take values or function as boolean values. The module even aids in the creation of help and version information, taking much of the work out of things.

However, sometimes you’ll need to support a large number of command line options, and representing each of them with a single letter becomes quite impractical after a certain point. Besides, short options can easily become very cryptic for the end user of your application. 

Fortunately, Perl makes it very easy to work with long options too, which, as you remember, can be represented by multiple letters. By making use of the appropriately-named Getopt::Long module, you can easily add broader support for command line options into your application. 

In this article, we’ll take a look at the Getopt::Long module and the functionality it offers for processing command line options. 

Getting started 

With Getopt::Std, we only had to call one function to process all of the command line options. That one function would then populate global variables (by default) with option values. Getopt::Long also has a single function, GetOptions, which handles the command line options, but it’s more complex. This function takes an even number of arguments, where the odd-numbered arguments are the option names (actually, they are the “specifications” and can contain more than just the names, but we’ll get into that later), and the even-numbered arguments are references to variables where the option values will be stored (again, it gets more complex than this—these are actually the “destinations”). 

Let’s see what this looks like in an actual script. Consider a program that can take just one command line option. This command line option will be named “force” and will make the program force some sort of operation. It doesn’t matter what that operation is because we’re not concerned with that here. We’re only concerned with the command line options, so let’s just print out the value of the command line option. Obviously, the option will have a boolean value, since it doesn’t take any values. If it’s present, it’s true. Otherwise, it’s false. 

We could call the program like this:


$ program –force


Or like this:


$ program


Here’s what the full script looks like:


#!/usr/bin/perluse strict;use Getopt::Long;my $force = '';GetOptions('force' =>  $force);print "force: $forcen";


As you can see, there’s nothing complicated here. The only thing you should keep in mind is that the variables you use need default values. Otherwise, if the command line option isn’t present, and you use the variable later on, you’ll get a warning if you have warnings enabled. 

{mospagebreak title=Handling values} 

What if we need for a command line option to take a value, though? This behavior is, of course, supported by the module, but we need to specify that a command line option can take a value. We also need to specify what kind of value the option can take. 

Suppose we want to add a command line option to our program called “server.” This option will take a value, the address of some server. This value will, of course, be a string. In order to specify all of this, we simply need to add a little bit to the option’s specifications (now you know why they are specifications, not names). All we need to add is an equals sign followed by the letter s, which indicates that we’re looking for a string:


GetOptions('force' =>  $force, 'server=s' =>  $server);


Before this, though, we need to declare the variable and give it a default value:


my $server = '';


You should also adjust the program so that it prints out the value of the option. 

Now the program can be called with the new command line option:


$ program –


What happens if we need spaces in the string, though? In that case, we would simply surround the string with quotation marks. For example, consider a command line option named “name” that takes the name of a person:


$ program –name=”John Smith”


We can specify other types of values, too: integers, floating point numbers and “extended integers.” This last type simply corresponds to integers as might be used in Perl. That is, they can be specified in hexadecimal, binary, or whatever. In order to specify that an option takes an integer value, use i, and in order to specify that an option takes a floating point value, use f. Extended integers may be specified by using the letter o. 

Here are three more command line options. The first takes an integer, the second takes a floating point number, and the third takes an extended integer:


my $retries = 0;my $somefloat = 0;my $einteger = 0;GetOptions('force' =>  $force, 'server=s' =>  $server, 'retries=i' =>  $retries, 'somefloat=f' => 
 =>  $einteger);


Now we can call the program like this:


$ program –retries=3 –somefloat=3.14 –einteger=0xFF


Say we try to pass the wrong kind of value to an option, though, like this:


$ program –retires=enough


We’re passing a string where the program expects a float. If you run this, though, you’ll notice that Getopt::Long complains:


Value "hi" invalid for option somefloat (real number expected)


In this case, the value is not assigned to the variable. 

{mospagebreak title=Optional values and multiple values} 

We just looked at how you can make a command line option take a value. However, there are a few more things you can do with values that are worth mentioning. 

First, you can make a value optional for a given command line option. For example, consider a program that normally operates silently, producing no command line output. However, you can give the user the option of making the program produce some output. Many programs operate like this. You can make a command line option called “verbose” that, when present, makes the program produce some output:


$ program –verbose


You might want to give the user the option to make the program print out even more output, though. This can be done by making the command line argument take an integer value that tells the program how verbose to be. A neat solution, though, would be to make this value optional. If the user specifies a value, then that value is used. Otherwise, it defaults to zero. Here’s a script that handles such an option:


#!/usr/bin/perluse strict;use Getopt::Long;my $verbose = 0;GetOptions('verbose:i' =>  $verbose);print "verbose: $verbosen";


Second, you’ll sometimes want a command line option to be used multiple times with multiple values. The Getopt::Long module allows for this. You simply need to pass an array reference rather than a scalar reference for the destination. 

Consider a command line option called “name” that takes a name. We might want to pass multiple names into the program by using this command line option more than once. So, we might run the program like this:


$ program –name Bob –name Anne


Here’s how this would look like in Perl:


my @names;GetOptions('names=s' =>  @names);print "$_n" for (@names);


The @names array would contain an element for each value. If we called the program as we did above, it would contain “Bob” and “Anne.” 

{mospagebreak title=Responding to command line arguments} 

The GetOptions function, as we’ve used it now, sets variables according to the values of command line options, or whether or not command line options are present. We can respond to these command line options by examining the variables later on the program. Sometimes, this is the appropriate approach. 

Other times, however, this is really inconvenient. Suppose we need more control over what happens when a command line option is encountered. Perhaps we want to set a variable whose value is determined by modifying the value from the command line. 

In order to do this, we can use a subroutine reference as a command line option’s destination in the GetOptions function. This subroutine will be called, with the first argument passed being the option name, and the second option being the value of that option (normally, but we won’t get into the exception in this article). 

Say that we want to condense multiple spaces in an option’s value. We could examine the variable set by GetOptions later on, but why not just collapse everything into one step? We can create a subroutine that does this for us, and then we can reference the subroutine in GetOptions. 

Here’s a script that does just that:


#!/usr/bin/perluse strict;use Getopt::Long;my $longstring = '';GetOptions('longstring=s' => &process_longstring);print "longstring: $longstringn";sub process_longstring { $longstring = @_[1]; $longstring =~ s/ {2,}/ /;}


It’s also possible to pass an anonymous subroutine. This works best for situations where we’re not doing a lot of work. Here’s our last script’s GetOptions function call, rewritten to use an anonymous subroutine:


GetOptions('longstring=s' => sub { $longstring = @_[1]; $longstring =~ s/ {2,}/ /; } );


We’ll end our exploration of the Getopt::Long module here. Although there are a number of additional features, I’ll leave them to you to uncover. You should at least have the basics down now, which are enough to create functional programs that take advantage of command line options.

Google+ Comments

Google+ Comments