运行“for (1 .. 80000000) { print qq#$_\n# }”时出现奇怪的 perl + zsh 行为

运行“for (1 .. 80000000) { print qq#$_\n# }”时出现奇怪的 perl + zsh 行为

我尝试在新打开的 zsh 会话中运行一个脚本,该脚本

$ perl -e "for (1 .. 80000000) { print qq#$_\n# }"

所以,我需要一些时间来输入它,然后它花了一些时间却什么也没做,几秒钟后(大约 5-10 秒)它打印了数千个......

/etc/motd
/etc/motd
/etc/motd
/etc/motd
/etc/motd
/etc/motd
/etc/motd
/etc/motd
...

我想知道为什么会发生这种情况,我想我可能会再次运行它,但要去的数字较少:

$ perl -e "for (1 .. 80) { print qq#$_\n# }" 

然后我收到了这条消息:

Backslash found where operator expected at -e line 1, near "motd\"
syntax error at -e line 1, near "motd\"
Missing right curly or square bracket at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

然后我尝试再次运行它,错误消息变成:

syntax error at -e line 1, near ") {"
Missing right curly or square bracket at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

有时:

Having no space between pattern and following word is deprecated at -e line 1.
Backslash found where operator expected at -e line 1, near "td\"
syntax error at -e line 1, near ") {"
Missing right curly or square bracket at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

尽管代码本身没有改变。

我认为它与我的 .zshrc 中的 /etc/motd 或其他东西有关,类似于“它当时正在加载它”,但这只有在打开 shell 几分钟后它没有出现时才有意义。

此外,每次我在“Konsole”(使用 zsh 4.3.17 和 perl 5.14.2)中打开新选项卡时都会出现这种奇怪的行为。

有趣的是,当我尝试使用以下命令查找我的 perl 版本时

perl -v

当我再次运行该脚本时,它给了我:

-v
-v
-v
-v
-v
-v
...

然后再次出现错误。使用 konsole 回显 $_ 得到:

$ echo $_
for (1 .. 80000000) { print qq#for (1 .. 80000000) { print qq#for (1 .. 80000000) { print qq#-v
# }
# }
# }

我就是搞不清楚那里发生了什么。所以,问题是:那里发生了什么?

答案1

在双引号中,shell 将展开$_,代表

前一个命令的最后一个参数。此外,此参数在每个执行的命令的环境中设置为该命令的完整路径名。

根据 zsh 手册页。由于此变量采用不同的值,因此在随后运行相同的命令行时会得到不同的结果。

因此,要么使用单引号来阻止 shell 对内联 perl 脚本进行大多数扩展(这是一个好主意):

$ perl -e 'for (1 .. 80000000) { print qq#$_\n# }'

或者,逃避美元符号:

$ perl -e "for (1 .. 80000000) { print qq#\$_\n# }"

相关内容