为什么仅仅使用'
而不是"
更改封闭我的单行会影响代码的行为?第一行代码生成了预期的内容,第二行代码给了(对我来说)一个意外的结果,打印出一个意外的数组引用。
$ echo "puke|1|2|3|puke2" | perl -lne 'chomp;@a=split(/\|/,$_);print $a[4];'
puke2
$ echo "puke|1|2|3|puke2" | perl -lne "chomp;@a=split(/\|/,$_);print $a[4];"
这是Perl版本:
$ perl -v
This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi
ARRAY(0x1f79b98)
答案 0 :(得分:4)
使用双引号,首先让shell插入变量。
正如您可以检查的那样,父shell在子管道分叉的子shell中未设置$_
和$a
。请参阅下面$_
的评论。
所以双引号版本实际上是
echo "puke|1|2|3|puke2" | perl -lne 'chomp;@a=split(/\|/);print [4];'
打印arrayref [4]
的内容。
评论让$_
暴露给Bash的影响。感谢Borodin提出这个问题。
$_
是Bash中少数special shell parameters之一。它包含上一个命令的最后一个参数,或者调用shell或命令的路径名(通过_
环境变量)。请参阅链接以获取完整说明。
但是,在这里它被分解为子shell,以运行perl
命令,它是第一个。显然它甚至没有设置,如
echo hi; echo hi | echo $_
打印一个空行(在hi
之后)。原因可能是_
环境变量没有为管道的子壳设置,但我不明白为什么会这样。例如,
echo hi; (echo $_)
使用hi
打印两行,即使( )
启动子shell。
在任何情况下,都不会设置给定管道中的$_
。
然后split
部分为split(/\|/)
,因此默认为split(/\|/, $_)
- 无需拆分。添加-w
后,这确实会显示使用未初始化$_
的警告。
请注意,此行为取决于shell。 tcsh
根本不会使用双引号来运行它。在ksh
和zsh
中,管道的最后一部分在主shell中运行,而不是子shell,因此$_
就在那里。
答案 1 :(得分:1)
这实际上是一个shell主题,而不是perl主题。
在shell中:
单引号保留它们包含的所有字符的文字值,包括$和反斜杠。但是,对于双引号,$,反引号和反斜杠字符具有特殊含义。
例如:
'\"'
评估为\"
,而
"\'"
评估为'
因为使用双引号,反斜杠作为转义字符具有特殊含义。