为什么从 ' 更改为 " 会影响这一行的行为?
why does changing from ' to " affect the behavior of this one-liner?
为什么简单地改变用 '
而不是 "
包围我的一行会影响代码的行为?第一行代码产生了预期的结果,第二行代码给出了(对我来说!)一个意想不到的结果,打印出一个意想不到的数组引用。
$ 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)
这实际上是一个 shell 主题,而不是 perl 主题。
在shell中:
单引号保留其包含的所有字符的字面值,包括 $ 和反斜杠。但是,对于双引号,$、反引号和反斜杠字符具有特殊含义。
例如:
'\"'
的计算结果为 \"
而
"\'"
的计算结果仅为 '
因为使用双引号,反斜杠作为转义字符具有特殊含义。
使用双引号让 shell 首先插入变量。
如您所见,$_
和 $a
在父 shell 为管道分叉的子 shell 中未设置。请参阅下面对 $_
的评论。
所以双引号版本有效
echo "puke|1|2|3|puke2" | perl -lne 'chomp;@a=split(/\|/);print [4];'
什么打印 arrayref [4]
。
评论 $_
接触 Bash 的影响。感谢 Borodin 提出这个问题。
$_
是 Bash 中为数不多的 special shell parameters 之一。它包含前一个命令的最后一个参数,或者调用 shell 或命令的路径名(通过 _
环境变量)。有关完整说明,请参阅 link。
然而,这里它被解释为分叉到 运行 perl
命令的子shell,这是第一个。显然它甚至没有设置,如
所示
echo hi; echo hi | echo $_
打印一个空行(在第一个 hi
之后)。原因可能是 _
环境变量没有为管道的 subshell 设置,但我不明白为什么会这样。例如,
echo hi; (echo $_)
使用 hi
打印两行,即使 ( )
启动子 shell.
无论如何,未设置给定管道中的 $_
。
split
部分然后是 split(/\|/)
,因此通过默认 split(/\|/, $_)
-- 没有任何东西可以拆分。随着 -w
添加,这确实打印了使用未初始化的 $_
.
的警告
请注意,此行为取决于 shell。 tcsh
根本不会 运行 带有双引号。在 ksh
和 zsh
管道的最后一部分 运行s 在主 shell 中,而不是子 shell,所以 $_
在那里。
为什么简单地改变用 '
而不是 "
包围我的一行会影响代码的行为?第一行代码产生了预期的结果,第二行代码给出了(对我来说!)一个意想不到的结果,打印出一个意想不到的数组引用。
$ 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)
这实际上是一个 shell 主题,而不是 perl 主题。
在shell中:
单引号保留其包含的所有字符的字面值,包括 $ 和反斜杠。但是,对于双引号,$、反引号和反斜杠字符具有特殊含义。
例如:
'\"'
的计算结果为 \"
而
"\'"
的计算结果仅为 '
因为使用双引号,反斜杠作为转义字符具有特殊含义。
使用双引号让 shell 首先插入变量。
如您所见,$_
和 $a
在父 shell 为管道分叉的子 shell 中未设置。请参阅下面对 $_
的评论。
所以双引号版本有效
echo "puke|1|2|3|puke2" | perl -lne 'chomp;@a=split(/\|/);print [4];'
什么打印 arrayref [4]
。
评论 $_
接触 Bash 的影响。感谢 Borodin 提出这个问题。
$_
是 Bash 中为数不多的 special shell parameters 之一。它包含前一个命令的最后一个参数,或者调用 shell 或命令的路径名(通过 _
环境变量)。有关完整说明,请参阅 link。
然而,这里它被解释为分叉到 运行 perl
命令的子shell,这是第一个。显然它甚至没有设置,如
echo hi; echo hi | echo $_
打印一个空行(在第一个 hi
之后)。原因可能是 _
环境变量没有为管道的 subshell 设置,但我不明白为什么会这样。例如,
echo hi; (echo $_)
使用 hi
打印两行,即使 ( )
启动子 shell.
无论如何,未设置给定管道中的 $_
。
split
部分然后是 split(/\|/)
,因此通过默认 split(/\|/, $_)
-- 没有任何东西可以拆分。随着 -w
添加,这确实打印了使用未初始化的 $_
.
请注意,此行为取决于 shell。 tcsh
根本不会 运行 带有双引号。在 ksh
和 zsh
管道的最后一部分 运行s 在主 shell 中,而不是子 shell,所以 $_
在那里。