Download as pdf or txt
Download as pdf or txt
You are on page 1of 2

Calling all who code. Take the 2023 Developer Survey.

How can I allow undefined options when parsing args with Getopt
Asked 12 years, 11 months ago Modified 11 years, 3 months ago Viewed 12k times

If I have a command line like:


19 my_script.pl -foo -WHATEVER

My script knows about --foo , and I want Getopt to set variable $opt_foo , but I don't know anything about -WHATEVER . How can I tell Getopt to
parse out the options that I've told it about, and then get the rest of the arguments in a string variable or a list?
An example:
use strict;
use warnings;

use Getopt::Long;

my $foo;

GetOptions('foo' => \$foo);

print 'remaining options: ', @ARGV;

Then, issuing
perl getopttest.pl -foo -WHATEVER

gives
Unknown option: whatever
remaining options:

perl getopt getopt-long

Share Improve this question Follow edited Feb 10, 2012 at 18:40 asked Jun 8, 2010 at 23:22
Ross Rogers
23.3k 27 108 164

3 Answers Sorted by: Highest score (default)

You need to configure "pass_through" option via Getopt::Long::Configure("pass_through");

23 Then it support actual options (e.g. stuff starting with "-" and without the special "--" delimiter to signify the end of "real" options).
Here's perldoc quote:
pass_through (default: disabled)
Options that are unknown, ambiguous or supplied with an invalid option value are passed through in instead of being flagged as errors.
@ARGV
This makes it possible to write wrapper scripts that process only part of the user supplied command line arguments, and pass the remaining
options to some other program.
Here's an example
$ cat my_script.pl
#!/usr/local/bin/perl5.8 -w

use Getopt::Long;
Getopt::Long::Configure("pass_through");
use Data::Dumper;
my %args;
GetOptions(\%args, "foo") or die "GetOption returned 0\n";
print Data::Dumper->Dump([\@ARGV],["ARGV"]);

$ ./my_script.pl -foo -WHATEVER


$ARGV = [
'-WHATEVER'
];

Join Stack OverflowShare


to findImprove
the best
thisanswer
answer toFollow
your technical question, Sign up with email Sign upedited Jun 9, 2010 at 14:31
with Google Sign up withanswered
GitHub Jun 8, 2010
Signatup23:53
with Facebook
help others answer theirs.
DVK
126k 32 210 325
1 A ha, that would explain why I didn't find it... :) – Ether Jun 9, 2010 at 0:08
4 I find it absolutely infuriating reading about some neat option on perldoc website and then go back to my mesosoic corporate Perl installation and find that the
exact perfect option I've found requires a flux capacitor, or at least a CPAN module upgrade – DVK Jun 9, 2010 at 0:31
1 Are you sure pass_through isn't available with 5.8? I just checked perldoc Getopt::Long for 5.6.1 (and you thought you were pre-historic ;)) and it's there.
– Zaid Jun 9, 2010 at 8:31
@Zaid - you're absolutely right! I didn't quite read the POD right and was looking for an option configured through import ; and this one is done via special
Configure() call. I have updated my answer. – DVK Jun 9, 2010 at 14:32

I just added a feature request to the MooseX::Getopt queue to allow such configuration: rt.cpan.org/Ticket/Display.html?id=58704 (so if you like it, please reply
with a "me too") :) – Ether Jun 23, 2010 at 18:11

Aren't the remaining (unparsed) values simply left behind in @ARGV ? If your extra content starts with dashes, you will need to indicate the end of the
options list with a :
1
--

#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Data::Dumper;

my $foo;
my $result = GetOptions ("foo" => \$foo);
print Dumper([ $foo, \@ARGV ]);

Then calling:
my_script.pl --foo -- --WHATEVER

gives:
$VAR1 = [
1,
[
'--WHATEVER'
]
];

PS. In MooseX::Getopt, the "remaining" options from the command line are put into the extra_argv attribute as an arrayref -- so I'd recommend
converting!
Share Improve this answer Follow edited Jun 9, 2010 at 0:09 answered Jun 8, 2010 at 23:41
Ether
52.8k 13 86 159
They aren't if they look like options. Instead, an error like Unknown option: WHATEVER will be issued to STDERR. – Robert P Jun 8, 2010 at 23:45
:] Indeed! Haha, I added an example like that to the question, too. – Robert P Jun 8, 2010 at 23:48

I think the answer here, sadly though, is "no, there isn't a way to do it exactly like you ask, using Getopt::Long, without parsing @ARGV on your
own." Ether has a decent workaround, though. It's a feature as far as most people are concerned that any option-like argument is captured as an
0 error. Normally, you can do
GetOptions('foo' => \$foo)
or die "Whups, got options we don't recognize!";

to capture/prevent odd options from being passed, and then you can correct the user on usage. Alternatively, you can simply pass through and
ignore them.
Share Improve this answer Follow answered Jun 8, 2010 at 23:50
Robert P
15.6k 10 68 112

Join Stack Overflow to find the best answer to your technical question, Sign up with email
help others answer theirs.

You might also like