我有一个按以下方式运行的脚本:
perl testing.pl -grid 24 -range 97 ## Here, arguments passed are processed via getopt::Long module.
Run Code Online (Sandbox Code Playgroud)
现在,我想检查传递给脚本的命令行参数的数量。预期是 2。但我得到 0。
我在脚本(testing.pl)中使用了下面的代码来提取参数的数量:
my $totalCmdLineArg = $#ARGV + 1;
print "$totalCmdLineArg is total command line arguments\n";
if ($totalCmdLineArg <= 0 ) {
$defaultmode=1;
} else {
$defaultmode=0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我得到“0 是命令行参数总数”作为输出。我希望“2 是总命令行参数”作为输出。我怎样才能得到预期的答案?
注意:有 100 多个参数,其中任何一个都可以传递。
GetOptions被调用后你就不能计算选项了。GetOptions删除它识别的选项@ARGV。引用其文档:
命令行选项取自数组@ARGV。完成 GetOptions 后,@ARGV 将包含命令行的其余部分(即非选项)。
此外,GetOptions不计算它解析了多少个选项。如果您需要有说服力,请查看来源。
因此,如果您想计算有多少个选项传递给您的程序,您必须在调用之前GetOptions手动执行此操作。
如果命令行上的所有参数都具有形式--option xxx,那么您可以简单地执行以下操作(在调用之前GetOptions):
my $totalCmdLineArg = grep { /^--/ } @ARGV
Run Code Online (Sandbox Code Playgroud)
--然而,这忽略了in 本身@ARGV标记选项列表结尾的事实。如果您的命令行类似于perl prog.pl --opt1 v1 --opt2 v2 -- some additional --argumentsthen--并且--arguments实际上不是选项(对于GetOptions)。要处理这种情况,您必须编写如下内容:
my $totalCmdLineArg = 0;
for (@ARGV) {
last if $_ eq '--';
$totalCmdLineArg++ if /^--/;
}
Run Code Online (Sandbox Code Playgroud)
-但是,这并没有考虑到单个选项可用于启动选项,并且可用于组合多个选项(is$Getopt::Long::bundling非零)的事实。您必须调整上面的代码来处理这种情况。
仅在最后的手段(不要在生产中使用,可能随时中断):
如果您正在使用bundling和其他复杂功能Getopt::Long,您可以稍微修改一下来计算实际找到的选项数量Getopt::Long。在内部,GetOptions调用FindOption实际寻找选项。您可以重新定义它来计算找到的选项数量:
my $opt_count = 0;
{
no warnings qw(redefine prototype);
my $original_FindOption = \&Getopt::Long::FindOption;
*Getopt::Long::FindOption = sub {
my @ret = &$original_FindOption;
if ($ret[0] && defined $ret[1]) {
$opt_count++;
}
return @ret;
};
}
Run Code Online (Sandbox Code Playgroud)
请注意,这是一种非常脆弱的方法:FindOption不是 的公开 API 的一部分Getopt::Long,因此可能会在版本之间发生变化,这可能会破坏此代码。
| 归档时间: |
|
| 查看次数: |
1880 次 |
| 最近记录: |