#!/bin/sh vs #!/usr/local/bin/python 在可执行文件中

#!/bin/sh vs #!/usr/local/bin/python in executables

pip节目中,She-bang是

#!/usr/local/bin/python

if __name__ == "__main__":
    # Python program body

在 Python 启动器提供的 Install Certificates.command 中:

#!/bin/sh

/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 << "EOF"

# python program body

EOF

这两种方法之间有什么区别吗?有什么理由比另一个更喜欢一个吗?

在我看来它们都是一样的,除了第二个多了一个 bash 子程序。这样对吗?

#! 行有行长度限制。也许他们这样做是为了解决这个问题。

选项是程序的路径,但前提是它足够短。 env python 使用路径。或者像这样链式加载。

在一般情况下,您只需指定您实际需要的解释器。

除此之外,您有时会看到像这样的解决方法作为可移植性黑客。在 POSIX 系统上,/usr/bin/env 很好地涵盖了大多数场景;但是,如果您需要对旧系统或其他特殊系统的可移植性,请回退到最低公分母,然后再回到可以可靠 运行 的地方,例如Python 在各种系统上可能需要各种不明显的结构。 (前一个 - 赞成! - Dan D. 的回答就是一个很好的例子。)

在某些情况下,您希望 sh 进行一些设置(例如,获取一些在使用 sh 语法的文件中指定的环境变量),然后 hand over execution 到 Python;

#!/bin/sh
# source some variables
. /etc/defaults/myenv.sh
# Then run Python
exec env python -c '
# ... Your Python script here
    ' "$@"

Install Certificates.command 脚本的特定代码已在 Python Issue #17128 中引入。据我所知,作者还没有解释他为什么这样写代码。

请注意,.command 文件是 Mac OS X 上的 Shell 脚本,可以通过在 Finder 中双击它们来执行。

我认为可能的解释是作者只是想尊重 Mac OS X 的期望 .command 文件应该是 Shell 脚本。

您可以将以下内容放入文件中进行测试 ~/Desktop/test.command:

#!/usr/bin/env python
print "Hello world"

然后在 Finder 中查看 Desktop 文件夹,注意它被报告为 "shell" 文件:

(虽然它被错误地报告为 Shell 文件,但这个 Python 脚本仍然可以通过双击它来执行。它不会破坏 Finder 或任何东西。)

要回答具体问题,如 Dan D. 所说,首选此模式的一个原因可能是避免 Shebang 行限制。

一般来说,您更愿意使用 #!/usr/bin/env python 作为您的 Shebang 行。创建 Bash Heredoc(即 python3.6 << EOF 模式)会产生各种问题,例如语法突出显示不起作用,您必须注意 Bash Heredoc 中的变量插值等