检测脚本是否正在通过 shebang 运行或被指定为命令行参数

检测脚本是否正在通过 shebang 运行或被指定为命令行参数

在 Pyenv 项目中,我们遇到了一个特殊的问题。

我们用 Bash 脚本(“shims”)替换python(和python*),这些脚本选择要在运行时运行的 Python 可执行文件。

现在,一些用户希望使用特殊的选择逻辑当 Python 脚本作为path/to/script.py.问题是,如果脚本运行为<python> path/to/script.py!,则不应应用此逻辑。

有没有办法可靠地区分这两种情况?

我找不到任何东西:根据第二种情况下命令行参数的制定方式,在两种情况下都可以执行完全相同的命令行:(
给出的 Bash 脚本不是真正的填充程序,只是一个演示示例展示我们的逻辑所看到和所做的)

$ cat python3 
#!/bin/bash
echo "'$0'"
for a in "$@"; do
  echo "'$a'"
done
# need to do the detection here
exec python3 "$@"

$ cat t.py 
#!/home/vmuser/python3
import sys
print(sys.argv)

$ $PWD/t.py
'/home/vmuser/python3' 
'/home/vmuser/t.py'
['/home/vmuser/t.py']

$ $PWD/python3 $PWD/t.py 
'/home/vmuser/python3'
'/home/vmuser/t.py'
['/home/vmuser/t.py']

既然 shebang 是一个 Linux 内核功能——也许它设置了一些指示该机制已被使用的指标?


我们考虑过要求用户在 Python 脚本中使用特殊的 shebang他们希望应用特殊逻辑,但是事实证明这个想法不受欢迎因为它使这些脚本无法移植。

答案1

既然 shebang 是一个 Linux 内核功能——也许它设置了一些指示该机制已被使用的指标?

是的,它确实。 Linux 将AT_EXECFN辅助向量条目设置为原始可执行文件的路径。在 C 语言中,您可以使用、 、 等char *at_execfn = (char*)getauxval(AT_EXECFN)来完成此操作。stat(at_execfn)

不过,从 bash 获取它是很棘手的。您可以尝试打开包装/proc/self/auxv然后查看/proc/self/mem。祝你好运;-)

相关内容