如何:# use perl eval 'exec perl -S $0 ${1+"$@"}' 设置 perl 版本?

dav*_*veg 3 shell perl

我必须调试一个旧的 perl 脚本,它显然是以一种我不理解的方式设置 perl 的版本......

: # use perl
    eval 'exec perl -S $0 ${1+"$@"}'
    if 0;
Run Code Online (Sandbox Code Playgroud)

perl -h说这-S意味着“使用 PATH 环境变量查找程序文件”。 $0是当前程序。我读过这$@意味着“来自最后一个eval命令的 Perl 语法错误消息”。但是他们为什么要加 1 呢?这一切是如何结合在一起的?它在做什么?

我必须调试的部分内容与它选择了我不想要的旧版本 perl 的事实有关。对于其他一切,我们使用#!/usr/bin/env perl它,我怀疑,可能会做同样的事情。我还怀疑我的解决方案可能在于修复$PATH(或防止弄乱它的代码弄乱它)。但我想通过更好地了解它现在如何选择版本来解决这个问题。

谢谢你的帮助 !

Sha*_*awn 5

这旨在通过首先将脚本视为然后执行 perl 的 shell 脚本来运行路径中首先出现的任何版本的 perl。在此上下文中,${1+"$@"}是传递给脚本的参数(如果有)。

从 bash 手册:

${parameter:+word}

如果参数为空或未设置,则不替换任何内容,否则替换单词的扩展。

省略冒号会导致仅对未设置的参数进行测试

perlrun 中有一个类似的例子:

此示例适用于具有与 Bourne shell 兼容的 shell 的许多平台:

#!/usr/bin/perl
eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
  if $running_under_some_shell;
Run Code Online (Sandbox Code Playgroud)

系统忽略第一行并将程序提供给/bin/sh,然后继续尝试将 Perl 程序作为 shell 脚本执行。shell 将第二行作为普通 shell 命令执行,从而启动 Perl 解释器。在某些系统$0上并不总是包含完整的路径名,所以-S如果需要,它会告诉 Perl 搜索程序。Perl 定位程序后,它会解析这些行并忽略它们,因为变量$running_under_some_shell永远不会为真。如果程序将由 csh 解释,则需要替换${1+"$@"}$*,即使它不理解参数列表中的嵌入空格(等等)。要启动 sh 而不是 csh,某些系统可能需要替换 #! 一行只包含一个冒号,Perl 会礼貌地忽略它。

使用/usr/bin/env是做同样事情的另一种方式,是的。