Getopts标记不带破折号的错误选项

时间:2020-02-07 20:03:00

标签: perl getopt getopt-long

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会解决这个问题。我想念什么?

3 个答案:

答案 0 :(得分:3)

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);
}

答案 1 :(得分:2)

Getopt::Long仅对选项起作用:以连字符开头的参数。如果没有传递(默认为no_pass_through),它将从@ARGV中删除它们,并保留所有非选项参数供您处理。如果您预期没有非选项参数,则可以在调用GetOptions之后保留任何参数的情况下,确定选项传递不正确。

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

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

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

答案 2 :(得分:1)

选项由前划线(连字符)表示;论据不是。

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

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