sai*_*l0r 1 shell perl double-quotes single-quotes
为什么只是简单地将我的单行'改为而不是"影响代码的行为?第一行代码产生了预期的结果,第二行代码给出了(给我!)一个意想不到的结果,打印出一个意想不到的数组引用。
$ 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];"
Run Code Online (Sandbox Code Playgroud)
这是 Perl 版本:
$ perl -v
This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi
ARRAY(0x1f79b98)
Run Code Online (Sandbox Code Playgroud)
使用双引号,您首先让 shell 插入变量。
正如您可以检查的那样,$_并且$a在子外壳中未设置由父外壳分叉为管道。请参阅$_下面的评论。
所以双引号版本是有效的
echo "puke|1|2|3|puke2" | perl -lne 'chomp;@a=split(/\|/);print [4];'
Run Code Online (Sandbox Code Playgroud)
什么打印 arrayref [4]。
关于$_接触 Bash的影响的评论。感谢Borodin提出这个问题。
该$_是屈指可数的一个特殊的shell参数中的Bash。它包含上一个命令的最后一个参数,或者调用 shell 或命令的路径名(通过_环境变量)。有关完整说明,请参阅链接。
但是,在这里它在子shell 中被解释为分叉运行perl命令,它的第一个。显然它甚至没有设置,如所见
echo hi; echo hi | echo $_
Run Code Online (Sandbox Code Playgroud)
打印一个空行(在 first 之后hi)。原因可能_是没有为管道的子外壳设置环境变量,但我不明白为什么会这样。例如,
echo hi; (echo $_)
Run Code Online (Sandbox Code Playgroud)
hi即使( )开始一个子shell ,也会打印两行。
在任何情况下,$_在给定的管道中都没有设置。
split然后该部分是split(/\|/),所以通过默认split(/\|/, $_)- 没有什么可以分割的。随着-w加入这个确实打印使用的未初始化的警告$_。
请注意,此行为取决于外壳。该tcsh不会在所有双引号运行此。在ksh和zsh管道的最后一部分在主壳,而不是一个子shell中运行,所以$_是存在的。