在使用Getopt解析args时,如何允许未定义的选项

时间:2010-06-08 23:22:41

标签: perl getopt getopt-long

如果我有一个命令行:

my_script.pl -foo -WHATEVER

我的脚本知道--foo,我希望Getopt设置变量$opt_foo,但我对-WHATEVER一无所知。我如何告诉Getopt解析我告诉它的选项,然后在字符串变量或列表中获取其余的参数?

一个例子:

use strict;
use warnings;

use Getopt::Long;

my $foo; 

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

print 'remaining options: ', @ARGV;

然后,发出

perl getopttest.pl -foo -WHATEVER

给出

Unknown option: whatever
remaining options:

3 个答案:

答案 0 :(得分:23)

您需要通过Getopt::Long::Configure("pass_through");

配置“pass_through”选项

然后它支持实际选项(例如以“ - ”开头且没有特殊“ - ”分隔符的东西来表示“真实”选项的结束)。

这是perldoc引用

  • pass_through(默认值:已禁用)

    未知,含糊不清或提供无效选项值的选项将在@ARGV中传递,而不是标记为错误。这使得编写包装脚本成为可能,该脚本只处理用户提供的部分命令行参数,并将剩余的选项传递给其他程序。

以下是一个示例

$ 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'
        ];

答案 1 :(得分:1)

剩下的(未解析的)值是不是只留在@ARGV?如果您的额外内容以短划线开头,则需要使用--指示选项列表的结尾:

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

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

然后致电:

my_script.pl --foo -- --WHATEVER

给出:

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

PS。在MooseX::Getopt中,命令行中的“剩余”选项作为arrayref放入extra_argv属性中 - 所以我建议转换!

答案 2 :(得分:0)

我认为这里的答案很遗憾,“不,没有办法完全像你问的那样,使用Getopt :: Long,而不需要自己解析@ARGV。”但是Ether有一个不错的解决方法。就大多数人而言,这是一个功能,任何类似选项的参数都被捕获为错误。通常,你可以做

GetOptions('foo' => \$foo) 
    or die "Whups, got options we don't recognize!";

捕获/阻止传递奇数选项,然后您可以在使用时更正用户。或者,您可以简单地通过并忽略它们。