【问题标题】:Force use of flags Getopt::Long强制使用标志 Getopt::Long
【发布时间】:2026-02-06 11:10:02
【问题描述】:

在使用 Getopt::Long 读取命令行参数时,有没有办法强制使用 -flags?以我目前的情况为例:

GetOptions('r=s' => \$var1,
              'lf=f' => \$var2,
              'uf=f' => \$var3,
              'trd=i' => \$var4,
              'vd=f' => \$var5)
or die("$usage");

如果仍然提供参数但没有标志(例如 -lf),则脚本不会退出或显示 $usage。相反,它无论如何都会运行,直到它后来不可避免地出错,因为参数没有被读入它们各自的变量(并且很可能是错误的顺序)。

【问题讨论】:

  • 不清楚您所说的“标志”是什么意思。如果您只使用-lf 作为选项运行上面的代码,那么GetOptions 将返回错误状态。您的意思是您希望某些选项是强制性的吗?
  • @Borodin 我的意思是 -lf、-uf、-trd 和 -vd。我可以通过以下方式运行脚本而不会出现错误结果:script.pl arg1 arg2 arg3 arg4。我期望这将无法运行,因为未提供:script.pl -lf arg1 -uf arg2 -trd arg3 -vd arg4。

标签: perl getopt-long


【解决方案1】:

问:当未提供选项时,GetOptions 不会返回错误结果

答:这就是为什么它们被称为“选项”。

来源:Getopt::Long documentation

您可以添加条件来检查标志的值,如果未定义,则调用die 或调用usage

【讨论】:

    【解决方案2】:

    Getopt::Long 将搜索您在GetOptions 调用中指定的所有命令行选项。它们都不是必需的,但单个选项可能需要具有特定类型的值,如果值丢失或类型错误,GetOptions 将返回 false 状态

    所有选项及其值都会从命令行中删除,剩下的任何东西都会像往常一样通过@ARGV 传递给程序

    大多数程序不需要在命令行上提供所有可能的选项,所以如果你想坚持指定所有选项,那么你可以简单地测试它们

    use List::Util 'all';
    
    die $usage unless all { defined } $var1, $var2, $var3, $var4, $var5;
    

    您可能还想要求没有未指定为选项之一的输入,在这种情况下,您只需检查@ARGV

    die $usage if @ARGV;
    

    【讨论】:

      【解决方案3】:

      稍后再检查。

      use File::Basename qw( basename );
      
      sub help {
          print(...);
          exit(0);
      }
      
      sub usage {
         if (@_) {
            my ($msg) = @_;
            chomp($msg);
            warn("$msg\n");
         }
      
         my $prog_name = basename($0);
      
         warn("Use $prog_name --help for more information\n");
         exit(1);
      }
      
      my ($var1, $var2, $var3, $var4, $var5);
      
      GetOptions(
         'help|h|?' => \&help,
         'r=s'      => \$var1,
         'lf=f'     => \$var2,
         'uf=f'     => \$var3,
         'trd=i'    => \$var4,
         'vd=f'     => \$var5
      )
          or usage();
      
      defined($var2)
         or usage("-lf must be provided");
      

      【讨论】: