![]() ESN 14339-080107-605240-85 |
|
Document Name: Perl Getopt and GetOptions Document Description: Perl Getopt and GetOptionsTwo Perl modules (Getopt and Getoptions::Long) work to extract program flags and arguments much like Getopt and Getopts do for shell programming. The Perl modules, especially GetOptions::Long, are much more powerful and flexible. Simple scripts show the power of these:
#!/usr/bin/perl
# script is "./g"
use Getopt::Std;
%options=();
getopts("od:fF",\%options);
# like the shell getopt, "d:" means d takes an argument
print "-o $options{o}\n" if defined $options{o};
print "-d $options{d}\n" if defined $options{d};
print "-f $options{f}\n" if defined $options{f};
print "-F $options{F}\n" if defined $options{F};
print "Unprocessed by Getopt::Std:\n" if $ARGV[0];
foreach (@ARGV) {
print "$_\n";
}
Trying it out: bash-2.05a$ ./g -f -d F -o -F -o 1 -d F -f 1 -F 1 bash-2.05a$ ./g -o -d foo -o 1 -d foo bash-2.05a$ ./g -o rough -d foo -o 1 Unprocessed by Getopt::Std: rough -d foo Processing of arguments stops when it saw "rough". If you leave off a required argument, it just gets swallowed: bash-2.05a$ ./g -d bash-2.05a$ ./g -d foo -d foo But it's easily confused: bash-2.05a$ ./g -d -o -f -d -o -f 1 It thinks that -o is the argument of -d. bash-2.05a$ ./g -k Unknown option: k Like the simple shell "getopt", this complains when it gets an option that it doesn't know about. Unlike the shell "getopt", prefacing the option string with a ":" doesn't help. Instead, use "getopt":
#!/usr/bin/perl
# we'll call this one ./gg
use Getopt::Std;
%options=();
getopt("odfF",\%options);
print "-o $options{o}\n" if defined $options{o};
print "-d $options{d}\n" if defined $options{d};
print "-f $options{f}\n" if defined $options{f};
print "-F $options{F}\n" if defined $options{F};
Note the lack of any ":". This module doesn't care which flags take values and which don't: it assumes ALL of them take arguments. The "getopt" isn't very bright: bash-2.05a$ ./gg -f -o -d foo -d foo -f -o bash-2.05a$ ./g -f -o -d foo -o 1 -d foo -f 1 But it doesn't complain: bash-2.05a$ ./gg -l bash-2.05a$ ./g -l Unknown option: l Unlike their shell cousins, neither of these have any issues with arguments containing spaces: bash-2.05a$ ./g -o -d "foo bar" -o 1 -d foo bar bash-2.05a$ ./gg -o "foo" -d "foo bar" -o foo -d foo bar Far better than either of these is the Getopt::Long module. Here's a script to play with it:
#!/usr/bin/perl
use Getopt::Long;
GetOptions("o"=>\$oflag,
"verbose!"=>\$verboseornoverbose,
"string=s"=>\$stringmandatory,
"optional:s",\$optionalstring,
"int=i"=> \$mandatoryinteger,
"optint:i"=> \$optionalinteger,
"float=f"=> \$mandatoryfloat,
"optfloat:f"=> \$optionalfloat);
print "oflag $oflag\n" if $oflag;
print "verboseornoverbose $verboseornoverbose\n" if $verboseornoverbose;
print "stringmandatory $stringmandatory\n" if $stringmandatory;
print "optionalstring $optionalstring\n" if $optionalstring;
print "mandatoryinteger $mandatoryinteger\n" if $mandatoryinteger;
print "optionalinteger $optionalinteger\n" if $optionalinteger;
print "mandatoryfloat $mandatoryfloat\n" if $mandatoryfloat;
print "optionalfloat $optionalfloat\n" if $optionalfloat;
print "Unprocessed by Getopt::Long\n" if $ARGV[0];
foreach (@ARGV) {
print "$_\n";
}
The hash array that this uses holds the argument name and the type of argument; what that points to is where it will store values for options processed. Playing with it: # # doesn't care if it's -o or --o bash-2.05a$ ./ggg -o oflag 1 bash-2.05a$ ./ggg --o oflag 1 # # abbreviating is ok too bash-2.05a$ ./ggg -verbose verboseornoverbose 1 bash-2.05a$ ./ggg -verb verboseornoverbose 1 # # but not this bash-2.05a$ ./ggg -verbosity Unknown option: verbosity # # $verboseonoverbose will be 0 here bash-2.05a$ ./ggg -noverb # # strings bash-2.05a$ ./gggg -s Option string requires an argument bash-2.05a$ ./ggg -s=foo stringmandatory foo bash-2.05a$ ./ggg -optional bash-2.05a$ ./ggg -optional=foo optionalstring foo # # ambiguity bash-2.05a$ ./ggg --opt Option opt is ambiguous (optfloat, optint, optional) # # floats and integers bash-2.05a$ ./ggg --optfloat=75.6 optionalfloat 75.6 bash-2.05a$ ./ggg --optint=75.6 Value "75.6" invalid for option optint (number expected) bash-2.05a$ ./ggg --optint=75 optionalinteger 75 bash-2.05a$ ./ggg -f --optfloat=75.6 -o Value "--optfloat=75.6" invalid for option float (real number expected) oflag 1 # once it runs out of options, it leaves @ARGV alone: bash-2.05a$ ./ggg -o foo bar oflag 1 Unprocessed by Getopt::Long foo bar GetOpt::Long is obviously much more flexible. The hash you pass is a little clumsy, but if you think about it, there's no better way to do it. In some places, you might use something like this:
#!/usr/bin/perl
use Getopt::Long;
my %moo=();
GetOptions("o"=>\$moo{$oflag},
"verbose!"=>\$moo{verbose},
"string=s"=>\$moo{stringmandatory},
"optional:s"=>\$moo{optionalstring},
"int=i"=> \$moo{mandatoryinteger},
"optint:i"=> \$moo{optionalinteger},
"float=f"=> \$moo{mandatoryfloat},
"optfloat:f"=> \$moo{optionalfloat});
foreach (keys %moo) {
print "$_ = $moo{$_}\n";
}
print "Unprocessed by Getopt::Long\n" if $ARGV[0];
foreach (@ARGV) {
print "$_\n";
}
but if you have so many flags that you are thinking that is helpful, your program is surely trying much too hard to be all things to all people. Author: Anthony Lawrence - Contact Author Publisher: Anthony Lawrence Licensee Name: Anthony Lawrence Reference URL: http://aplawrence.com/Unix/perlgetopts.html Copyright: All Rights Reserved Registration Date: 1/7/2008 8:53:10 PM UTC Views: 161055 |
