这个 Perl shebang 是如何工作的? (对于不是来自 Perl 的人)

How does this Perl shebang work? (For someone not coming from Perl)

有人可以解释一下这个 shebang 是如何工作的吗?

#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/python3/r,$_)

我看到它在这里发布了两次,但不是来自 Perl,我觉得它很神奇。 我想将目录调整为相对于脚本的 python 环境。

#!../env/bin/python3 到(我只是在这里猜测)#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/env/bin/python3/r,$_)

编辑:我正在尝试执行一个简单的“Hello world”程序。

#!/usr/bin/perl -e'$_=$ARGV[0];exec(s{\w+$}{exploit-env/bin/python3}r,$_)'

###############################

def main():
    print('Hello world')

###############################

if __name__ == '__main__':
    main()

Shebang 处理在所有系统中并不一致[1],但您的系统显然执行了以下 shell 命令将执行的操作(假设文件包含shebang 是 /path/to/script):

/usr/bin/perl -e'$_=$ARGV[0];exec(s/\w+$/python3/r,$_)' /path/to/script

(脚本的路径可能不是绝对路径——它可能是相对于当前目录的——但在这里无关紧要。)

脚本从 /path/to/script 生成 /path/to/python3(通过替换结尾的 "word" 字符,包括字母、数字和下划线,但不包括 /),然后计算

exec('/path/to/python3', '/path/to/script')

用 Python 解释器替换当前进程中的程序 运行ning,将路径作为参数传递给脚本。


如果我没看错的话,你想 运行 /path/to/../env/bin/python3 而不是 /path/to/python3。为此,请使用以下任一方法:

#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/..\/env\/bin\/python3/r,$_)

#!/usr/bin/perl -e$_=$ARGV[0];exec(s{\w+$}{../env/bin/python3}r,$_)

/ 在使用 / 作为分隔符时需要被 \ 转义(第一种解决方案),但我们可以更改分隔符以产生更具可读性的结果(第二种解决方案)。


你提出的 shebang 导致争论被吸收。将 $_ 替换为 @ARGV 以传递它们。

#!/usr/bin/perl -e$_=$ARGV[0];exec(s{\w+$}{../env/bin/python3}r,@ARGV)

  1. 至少在历史上,一些系统将 #! 之后的整个序列视为路径(即不允许使用参数),而一些系统对路径的长度有非常严格的限制。