Perl Getopt and GetOptions
By Tony Lawrence2005-04-22
Perl Getopt and GetOptions
Simple scripts show the power of these:
#!/usr/bin/perlTrying it out:
# 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";
}
bash-2.05a$ ./g -f -d F -o -FProcessing of arguments stops when it saw "rough".
-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
If you leave off a required argument, it just gets swallowed:
bash-2.05a$ ./g -dBut it's easily confused:
bash-2.05a$ ./g -d foo
-d foo
bash-2.05a$ ./g -d -o -fIt thinks that -o is the argument of -d.
-d -o
-f 1
bash-2.05a$ ./g -kLike 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":
Unknown option: k
#!/usr/bin/perlNote the lack of any ":". This module doesn't care which flags take values and which don't: it assumes ALL of them take arguments.
# 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};
The "getopt" isn't very bright:
bash-2.05a$ ./gg -f -o -d fooBut it doesn't complain:
-d foo
-f -o
bash-2.05a$ ./g -f -o -d foo
-o 1
-d foo
-f 1
bash-2.05a$ ./gg -lUnlike their shell cousins, neither of these have any issues with arguments containing spaces:
bash-2.05a$ ./g -l
Unknown option: l
bash-2.05a$ ./g -o -d "foo bar"Far better than either of these is the Getopt::Long module. Here's a script to play with it:
-o 1
-d foo bar
bash-2.05a$ ./gg -o "foo" -d "foo bar"
-o foo
-d foo bar
#!/usr/bin/perlThe 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.
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";
}
Playing with it:
#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:
# 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
#!/usr/bin/perlbut 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.
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";
}
Tutorial pages:
|
© Copyright 2005 A.P. Lawrence
|
|||||||||
You might also want to check these out:
|
Leave a Comment on "Perl Getopt and GetOptions"
You must be logged in to post a comment.
Link to This Tutorial Page!

