将 0 作为命令行参数传递的问题

Posted

技术标签:

【中文标题】将 0 作为命令行参数传递的问题【英文标题】:problem passing 0 as command-line argument 【发布时间】:2011-03-31 13:20:38 【问题描述】:

当我将 0 作为命令行参数传递给脚本时,我刚刚注意到 perl5 (5.10.0) 的一个奇怪行为,该脚本将其分配给一个变量。我遇到的问题是,如果我在脚本中给变量一个大于 0 的默认值,比如 1,那么我可以传递除 0 之外的任何值来覆盖默认值 1。

以下是我使用的'test.pl'的代码:

#!/usr/bin/perl -w  
my $x = shift || 1;  
print "x is $x\n";  

以下是我测试时的命令和输出:

$ ./test.pl 2  
x is 2  
$ ./test.pl 0  
x is 1  

如果有人能阐明这一点,我将不胜感激。谢谢。 ww

【问题讨论】:

【参考方案1】:

如果您希望$x 在未提供参数的情况下具有“1”的值,请使用:

my $x = shift // 1;  

来自 perldoc perlop:

“//”与“||”完全相同, 除了它测试左侧的定义性而不是它的 真相。

注意:defined-or 运算符从 5.10(2007 年 12 月 18 日发布)开始可用

【讨论】:

我感觉这是在相当新的 Perl 版本中引入的,你能说一下是哪一个吗?然后我会 +1。 @gbacon:谢谢。由于我们中的很多人仍在使用早期版本,您能否在回答中提及这一点,请 eugene y?谢谢。 感谢所有回答的人。没想到这么快就得到了答复。谢谢,尤金,我猜你是第一个回答的人。【参考方案2】:

最好的方法是 eugene 和 Alexandr 的答案中的那个,但是如果你坚持使用旧的 perl,请使用

my $x = shift;
$x = 1 unless defined $x;

因为您只有一个可选参数,您可以在标量上下文中检查 @ARGV 以检查存在多少命令行参数。如果它在那里,请使用它,或者以其他方式回退到默认值:

my $x = @ARGV ? shift : 1;

【讨论】:

【参考方案3】:

使用定义或运算符,因为字符串“0”已定义,但未评估为真。

#!/usr/bin/perl -w  
my $x = shift // 1;  
print "x is $x\n";  

【讨论】:

是的,但正如 gbacon 在其他地方的评论中提到的那样,这确实需要 Perl 5.10 或更高版本。 j_random_hacker:Wayne 使用的是 5.10.0,已经 2.5 年了。【参考方案4】:

在这一行my $x = shift || 1; 中,移位未通过测试,因此条件逻辑 OR || 被执行并为其分配了 1...根据shift 上的页面,值为 0,这意味着空数组。 ...

【讨论】:

【参考方案5】:

表达式shift || 1 选择右轴当且仅当左轴计算结果为“假”。由于您传递的是 0,其计算结果为“false”,$x 最终的值为 1。

【讨论】:

以上是关于将 0 作为命令行参数传递的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 argparse 将列表作为命令行参数传递?

为啥在将命令行图像文件中的参数作为参数传递时出现错误

如何将字符串语句作为命令行参数传递

我应该如何将密码(包含特殊字符)作为命令行参数传递?

将元组作为命令行参数传递

python argh/argparse:如何将列表作为命令行参数传递?