为什么perl -e“ print lc” Hello-World \ n“”打印0

时间:2018-10-15 12:38:53

标签: bash macos perl

我有一个要在命令行中使用perl的-e选项调试的代码。 (确切地说,是从Mac OS终端上来的)

当我这样调用子例程时,我忘记正确匹配双引号,有点像这样:

perl -e "print lc "Hello-World\n""
#Output: 0

我很惊讶地看到0,但是在仔细看后,我发现我的双引号有问题。毫不奇怪,使用外部单引号可以解决问题

perl -e 'print lc "Hello-World\n"'
# Output(fixed): hello-world

现在,我知道问题出在哪里,我很高兴看到它首先返回0。好像bash进行了某种减法运算,因为如果我在那儿没有破折号而重复了同样的错误,即使双引号错误,我也不会遇到这个问题:

perl -e "print lc "HelloWorld\n""
                  ^ closing the quotes too soon
#Output: helloworldn

那么为什么该语法perl -e "print lc "Hello-World\n""打印0?

3 个答案:

答案 0 :(得分:11)

有一个有用的技巧来找出什么是perl在“思考”。

运行perl -MO=Deparse -e "print lc "Hello-World\n""

perl -MO=Deparse -e "print lc "Hello-World\n""
print lc 'Hello' - 'Worldn';
-e syntax OK

这里发生的是perl在“看到” Hello - Worldn作为算术和。并且由于字符串在数字上为零,因此您正在打印0-0。它与bash无关,而与perl及其如何处理数字值无关。

这是因为如果您不使用strictwarnings,则裸字是可以接受的,但是通过减法(例如0)可以将其强制为数字值

如果您打开了warnings

perl -Mwarnings -e "print lc "Hello-World\n""
Argument "Worldn" isn't numeric in subtraction (-) at -e line 1.
Argument "Hello" isn't numeric in subtraction (-) at -e line 1.

答案 1 :(得分:4)

以下内容对于查看由perl解析的代码很有用:

$ perl -MO=Deparse -e "print lc "Hello-World\n""
print lc 'Hello' - 'Worldn';

'Hello''Worldn'转换为int的值为0。

答案 2 :(得分:2)

在单线内,我倾向于使用generalized quotes来避免这些问题:

$ perl -e "print lc qq(Hello-World\n)"

如果仅在换行符处使用双引号,则可以使用-l开关向每个print(但不printf)添加换行符:

$ perl -le "print lc 'Hello-World'"

使用-E,您可以启用v5.10功能,包括say,该功能还会在输出中添加换行符:

$ perl -E "say lc 'Hello-World'"

您已将其标记为macOS,这意味着您可以对-e的参数使用单引号(Windows不允许这样做):

$ perl -e 'print lc qq(Hello-World\n)'
$ perl -e 'print lc "Hello-World\n"'

在像shell这样的Unix上的双引号中,以$开头的是变量。失败是因为Shell在Perl甚至没有看到程序字符串(它是$HOME)之前就插入print /Users/brian。这是一个愚蠢的示例,但它显示了问题:

 $ perl -le "print $HOME"
 Unknown regexp modifier "/b" at -e line 1, at end of line
 Unknown regexp modifier "/r" at -e line 1, at end of line
-e had compilation errors.

请转义$或使用单引号:

 $ perl -le "print \$HOME"
 $ perl -le 'print  $HOME'