我必须调试一个旧的 perl 脚本,它显然是以一种我不理解的方式设置 perl 的版本......
: # use perl
    eval 'exec perl -S $0 ${1+"$@"}'
    if 0;
perl -h说这-S意味着“使用 PATH 环境变量查找程序文件”。  $0是当前程序。我读过这$@意味着“来自最后一个eval命令的 Perl 语法错误消息”。但是他们为什么要加 1 呢?这一切是如何结合在一起的?它在做什么?
我必须调试的部分内容与它选择了我不想要的旧版本 perl 的事实有关。对于其他一切,我们使用#!/usr/bin/env perl它,我怀疑,可能会做同样的事情。我还怀疑我的解决方案可能在于修复$PATH(或防止弄乱它的代码弄乱它)。但我想通过更好地了解它现在如何选择版本来解决这个问题。
谢谢你的帮助 !
这旨在通过首先将脚本视为然后执行 perl 的 shell 脚本来运行路径中首先出现的任何版本的 perl。在此上下文中,${1+"$@"}是传递给脚本的参数(如果有)。
从 bash 手册:
${parameter:+word}如果参数为空或未设置,则不替换任何内容,否则替换单词的扩展。
和
省略冒号会导致仅对未设置的参数进行测试
perlrun 中有一个类似的例子:
此示例适用于具有与 Bourne shell 兼容的 shell 的许多平台:
Run Code Online (Sandbox Code Playgroud)#!/usr/bin/perl eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}' if $running_under_some_shell;系统忽略第一行并将程序提供给
/bin/sh,然后继续尝试将 Perl 程序作为 shell 脚本执行。shell 将第二行作为普通 shell 命令执行,从而启动 Perl 解释器。在某些系统$0上并不总是包含完整的路径名,所以-S如果需要,它会告诉 Perl 搜索程序。Perl 定位程序后,它会解析这些行并忽略它们,因为变量$running_under_some_shell永远不会为真。如果程序将由 csh 解释,则需要替换${1+"$@"}为$*,即使它不理解参数列表中的嵌入空格(等等)。要启动 sh 而不是 csh,某些系统可能需要替换 #! 一行只包含一个冒号,Perl 会礼貌地忽略它。
使用/usr/bin/env是做同样事情的另一种方式,是的。