代码之家  ›  专栏  ›  技术社区  ›  Ross Rogers

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

  •  19
  • Ross Rogers  · 技术社区  · 14 年前

    如果我有如下命令行:

    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 回复  |  直到 12 年前
        1
  •  23
  •   DVK    14 年前

    您需要通过配置“pass\u through”选项 Getopt::Long::Configure("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'
            ];
    
        2
  •  1
  •   Ether    14 年前

    剩下的(未分析的)值不是简单地留在 @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 extra_argv 属性作为arrayref——所以我建议转换!

        3
  •  0
  •   Robert P    14 年前

    我认为这里的答案是“不,没有一种方法可以完全像你所要求的那样,使用Getopt::Long,而不用自己解析@ARGV。”尽管如此,Ether还是有一个不错的解决方法。对于大多数人来说,这是一个特性,像参数这样的任何选项都会被捕获为错误。通常,你可以

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

    捕获/防止传递奇数选项,然后可以更正用户的用法。或者,你可以简单地通过并忽略它们。