首页 > 解决方案 > getopt::long 如何与混合多头/空头期权一起使用?

问题描述

Getopt 描述说,'-' 和 '--' 都可以用于同一个选项,并且可以捆绑短选项。假设“帮助”是一个选项,那么:

script --help     # succeeds
script --h        # succeeds
script -h         # fails

如果我们有两个或多个具有唯一首字符(“ab”、“cd”)的选项,则 -ac 不起作用,但 --a 和 --c 起作用。我查看了所有的 getopt 选项,我认为正确使用了它们。我错过了一个选项还是我误解了 getopt 描述?

实际代码是:

      Getopt::Long::Configure ( "gnu_getopt"
                              , "auto_abbrev"
                              , "bundling"
                              , "ignore_case_always"
                              );

      GetOptions ( 'normalize'   => \$normalize
                 , 'exclude=s'   => \@exclude
                 , 'help'        => \$help
                 , 'include=s'   => \@include
                 , 'recurse'     => \$recurse
                 , 'update'      => \$update
                 , '2update'     => \$update2
                 , 'copy'        => \$copy
                 , 'move'        => \$move

                 , 'n'           => \$normalize
                 , 'e=s'         => \@exclude
                 , 'h'           => \$help
                 , 'i=s'         => \@include
                 , 'r'           => \$recurse
                 , 'u'           => \$update
                 , '2'           => \$update2
                 , 'c'           => \$copy
                 , 'm'           => \$move
                 );

使用重复的 getopts 参数可以识别“-h”和“--h”。使用重复的选项,事情似乎按预期工作,但我对 getopt 描述的阅读似乎表明重复的代码是不必要的。

标签: perl

解决方案


bundling,-- 必须用于长选项。-只能用于短选项,您没有定义。

您可以禁用捆绑(nobundlingafter gnu_getopt,而不是bundling已经启用的gnu_getopt)。

use Getopt::Long qw( );

for (
   [qw( --help )],
   [qw( --h )],
   [qw( -h )],
) {
   @ARGV = @$_;
   say "@ARGV";

   Getopt::Long::Configure(qw( gnu_getopt nobundling auto_abbrev ignore_case_always ));
   Getopt::Long::GetOptions(
      'normalize' => \my $normalize,
      'exclude=s' => \my @exclude,
      'help'      => \my $help,
      'include=s' => \my @include,
      'recurse'   => \my $recurse,
      'update'    => \my $update,
      '2update'   => \my $update2,
      'copy'      => \my $copy,
      'move'      => \my $move,
   );

   say $help // "[undef]";
}

或者,您可以一次性使用help|h定义 long ( --) 和 short ( -) 选项。

use Getopt::Long qw( );

for (
   [qw( --help )],
   [qw( --h )],
   [qw( -h )],
) {
   @ARGV = @$_;
   say "@ARGV";

   Getopt::Long::Configure(qw( gnu_getopt auto_abbrev ignore_case_always ));
   Getopt::Long::GetOptions(
      'normalize|n' => \my $normalize,
      'exclude|e=s' => \my @exclude,
      'help|h'      => \my $help,
      'include|i=s' => \my @include,
      'recurse|r'   => \my $recurse,
      'update|u'    => \my $update,
      '2update|2'   => \my $update2,
      'copy|c'      => \my $copy,
      'move|m'      => \my $move,
   );

   say $help // "[undef]";
}

两个程序都输出以下内容:

--help
1
--h
1
-h
1

推荐阅读