【问题标题】:Getopts to flag bad options without dashGetopts 标记不带破折号的错误选项
【发布时间】:2020-02-07 20:03:00
【问题描述】:
Getopt::Long::Configure("no_pass_through");
my %opts = ();
GetOptions(\%opts,
           'opt1=s',
           'opt2=s',
           'opt3'
          );

test.pl bad_option_without_dash

当错误的选项不带破折号传递时,如何让 getopts 标记错误?我期待no_pass_through 会处理这个问题。我错过了什么?

【问题讨论】:

  • 查看Getopt::Long 文档,注意描述部分的第一段——你会发现你缺少什么。

标签: perl getopt getopt-long


【解决方案1】:

Getopt::Long 只是提取选项。由您来验证这些选项和非选项参数的值(留在@ARGV 中)。

具体来说,如果你想确保只传递了选项,那么你可以使用

@ARGV == 0
   or die("usage\n");

我用什么:

use Getopt::Long qw( );

my ( $opt_opt1, $opt_opt2, $opt_opt3 );

sub parse_args {
   ( $opt_opt1, $opt_opt2, $opt_opt3 ) = ();

   Getopt::Long::Configure(qw( posix_default ));
   Getopt::Long::GetOptions(
      'help|h|?' => \&help,
      'opt1=s'   => \$opt_opt1,
      'opt2=s'   => \$opt_opt2,
      'opt3'     => \$opt_opt3,
   )
      or usage();

   # Validate $opt_* here if necessary.

   !@ARGV
      or usage("Too many arguments.");

   return @ARGV;
}

sub main {
   # my () = @_;   # This program doesn't accept non-option args.
   ...
}

main(parse_args());

助手:

use File::Basename qw( basename );

sub help {
   my $prog = basename($0);
   print
"Usage:
  $prog [options]
  $prog --help

Options:
  --opt1 FOO
      ...

  --opt2 BAR
      ...

  --opt3
      ...
";
   exit(0);
}

sub usage {
   if (@_) {
      my ($msg) = @_;
      chomp($msg);
      say STDERR $msg;
   }

   my $prog = basename($0);
   say STDERR "Try '$prog --help' for more information.";
   exit(1);
}

【讨论】:

  • 为什么这种健全性检查不是实施的一部分?即如果Getopt::Long::Configure("no_stray_options");,则不允许杂散选项
  • 没有所谓的流浪选项。不属于选项的第一个值(包括-- 之后的第一个值)和所有后续值都是程序的参数。 GetOptions 无法知道您的程序需要多少个参数,添加一种机制来告诉它也没有意义,因为这比自己进行检查更复杂(因为有些程序需要固定数量的参数,而有些期望一个封闭的范围,而有些期望一个开放的范围)。
  • 哈哈。我写的是“由你决定”而不是“由你决定”。 (固定)
【解决方案2】:

Getopt::Long 仅对选项起作用:以连字符开头的参数。如果没有 passthrough(no_pass_through 是默认值),它将从 @ARGV 中删除它们,留下任何非选项参数供您处理。如果您期望没有非选项参数,那么如果在调用 GetOptions 后仍有任何参数,您可以确定选项传递不正确。

die "Usage: $0 [--opt1=string] [--opt2=string] [--opt3]\n" if @ARGV;

GetOptions 的返回值也很有用,因为它会指示是否找到任何无法识别或无效的选项。

GetOptions(...) or die "Usage: $0 ...\n";

【讨论】:

    【解决方案3】:

    选项用前导破折号(连字符)表示;论据不是。

    您可能会发现Getopt::Long Argument-callback 很有用:

    一个特殊的选项'name' 可以用来指定一个子程序来处理非选项参数。当 GetOptions() 遇到一个看起来不像选项的参数时,它会立即调用这个子例程并传递一个参数:参数名称。

    【讨论】:

      猜你喜欢
      • 2021-10-20
      • 2015-09-16
      • 2014-05-14
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 1970-01-01
      相关资源
      最近更新 更多