我正在使用 Getopt::Long 将选项传递给我的 Perl 脚本。
但我想做这样的事情:
perl myScript mandatoryArgument1 -optionalArgument1=someValue
如果缺少mandatoryArgument1,我希望脚本抛出错误。如何做到这一点?
最佳答案
好的Getopt::Long
没有这样的机制。具体是processes options .
但是,当它执行它的工作时,它会从 @ARGV
中删除这些选项。因此,一旦完成,您就可以检查是否存在预期的参数。请参阅第二部分,但我想首先建议另一种方法:将这些参数命名,然后 Getopt
将处理它们。
然后很容易检查它们是否已提交。例如
use warnings;
use strict;
use feature 'say';
use Getopt::Long;
my $mandatoryArg;
my $opt;
# Read command-line arguments, exit with usage message in case of error
GetOptions( 'name=s' => \$mandatoryArg, 'flag' => \$opt )
or usage();
if (not defined $mandatoryArg) {
say STDERR "Argument 'name' is mandatory";
usage();
}
# The program goes now. Value for $opt may or may have not been supplied
sub usage {
say STDERR "Usage: $0 ..."; # full usage message
exit;
}
所以如果 --name string
没有在命令行中给出 $mandatoryArg
保持未定义并且程序退出。该变量不需要默认值,因为它是强制性的,而且它不应该有一个默认值来进行此检查。
参数检查和处理通常要复杂得多,这就是 Getopt
闪耀。
mandatoryArgument1
在问题中提供了没有名称。而Getopt
可以发到act on a non-option input ,它无法检测到预期的不在那里。†
该模块允许在命令行的任何位置混合参数和命名选项。见 Option with other arguments在文档中。所以你可以调用程序
script.pl --opt1 value1 unnamed_arg --opt2 value2
但我建议用户在命名选项之后提供它们。
然后,在 GetOptions
之后做它的工作,@ARGV
将包含字符串 unnamed_arg
你可以得到它(或发现它不存在)。 GetOptions
处理命名选项和上面一样。
my ($var1, $var2, $flag);
GetOptions('opt1=s' => \$var1, 'opt2=i' => \$var2, 'f' => \$flag)
or usage();
# All supplied named options have been collected, all else left in @ARGV
# Read the remaining argument(s) from @ARGV, or exit with message
# This can get far more complicated if more than one is expected
my $mandatoryArg1 = shift @ARGV || do {
say STDERR "Mandatory argument (description) is missing";
usage();
};
以上必须处理@ARGV
手工一次Getopt
拾取命名参数。
如果有多个这样的参数,用户必须严格遵守他们在命令行上的预期相对位置,因为程序通常无法分辨出什么是什么。因此,用户在命令行上混淆了他们的顺序的错误通常不会被捕获。
这会成为一个障碍,我建议最多有一个种未命名的参数,并且仅在必须是什么很明显的情况下,例如文件名)。
虽然所有这些都是可能的模块,例如 Getopt
准确地存在,因此我们不必这样做。
† 使用 '<>'
的“名称”设置看起来不像选项的输入操作
Getoptions( 'opt=s' => \$var, ..., '<>' => \&arg_cb );
sub arg_cb { say "Doesn't look like an option: $_[0]" }
子arg_cb
仅当看到非选项参数时才调用。
关于perl - 如何将强制和可选命令行参数传递给 perl 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37453445/