【问题标题】:How does this Perl shebang work? (For someone not coming from Perl)这个 Perl shebang 是如何工作的? (对于不是来自 Perl 的人)
【发布时间】:2020-06-10 13:49:48
【问题描述】:

有人能解释一下这个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()

【问题讨论】:

  • ShebangNix 特定的。文件如何命名,同一个 dir 中是否还有其他文件?

标签: python perl virtualenv shebang


【解决方案1】:

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(通过替换结尾的“单词”字符,包括字母、数字和下划线,但不包括/),然后计算

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

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


如果我在字里行间正确阅读,您想运行/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. 至少从历史上看,一些系统将#! 之后的整个序列视为路径(即不允许任何参数),而一些系统对路径的长度有非常严格的限制。

【讨论】:

  • 我刚刚意识到这会阻止使用命令行参数。我试过#!/usr/bin/perl -e$_=join(' ', @ARGV);exec(s{\w+$}{../exploit-env/bin/python3}r,$_),但没有骰子。有什么想法吗?
  • @ARGV替换$_
最近更新 更多