为什么有些 python 脚本以 #!/usr/bin/env python 开头?

Lin*_*edi 55 python scripts

我注意到一些 python 脚本以

#!/usr/bin/env python
Run Code Online (Sandbox Code Playgroud)

代替

#!/usr/bin/python
Run Code Online (Sandbox Code Playgroud)

python 脚本是唯一使用的脚本#!/usr/bin/env吗?是否有任何以例如#!/usr/bin/env bash或开头的脚本#!/usr/bin/env perl?如果不是,那么为什么 python 脚本不同?

Jac*_*ijm 67

在脚本的shebang中使用env

在这一点上,Python 脚本与任何其他语言的脚本没有什么不同。

如果脚本是可执行的,并且在没有前面的语言的情况下调用,则使用#!/usr/bin/env python#!/usr/bin/python会起作用。然后脚本调用语言的解释器来运行脚本中的代码,在您的示例中,shebang 是查找.python

使用#!/usr/bin/env python而不是绝对(完整路径)#!/usr/bin/python确保找到 python(或任何其他语言的解释器),以防它在不同的类似 Linux 或 Unix 的发行版中可能不在完全相同的位置,如解释例如这里

虽然#!/usr/bin/python可以在默认的 Ubuntu 系统上运行,但最好使用它 #!/usr/bin/env python

关于环境

env是一个可执行的/usr/bin或者,由@hvd提到的(感谢提示!),可作为一个兼容性符号链接/usr/binenv,在几乎所有的Linux发行版。

来自维基百科


env 是 Unix 和类 Unix 操作系统的 shell 命令。它用于打印环境变量列表或在更改的环境中运行另一个实用程序,而无需修改当前存在的环境。使用 env,可以添加或删除变量,并且可以通过为它们分配新值来更改现有变量。

关于你的问题:

在实践中, env 有另一个常见用途。shell 脚本经常使用它来启动正确的解释器。在这种用法中,环境通常不会改变


更多信息env可以在这里找到,并且一如既往地在man env(从终端)中找到。


关于shebang的附加信息;为什么 #!python 不起作用?

在评论中,有人问为什么我们不能简单地#!python用作shebang。由于口译员在$PATH,这个想法是可以理解的。

原因是可执行文件由 执行execve,我们可以在此处阅读。具体线路:

解释器脚本是一个启用了执行权限的文本文件,其第一行的格式如下:

#! interpreter [optional-arg]

解释器必须是 可执行文件有效路径名 ....

解释execve需要一个完整(有效)的解释器路径。这是有道理的,因为脚本(任何语言的)也可以在启动期间的任何时刻运行,可能在$PATH设置之前。

  • 为了完整起见,因为这并不是 Ubuntu 特有的,所以没有正式要求 `/usr/bin/env` 的存在,而不是要求 `/usr/bin/python` 的存在。例如,它可以合法地以 `/bin/env` 的形式存在。只是在实践中,几乎每个发行版都直接或通过兼容性符号链接将 `env` 作为 `/usr/bin/env` 提供。 (7认同)
  • 作为提示,您应该始终执行 #!/usr/bin/env python2 或 #!/usr/bin/env python3。您应该始终让您的 Python 脚本使用特定版本的解释器,而不是只使用“python”。 (4认同)
  • @hvd 幸运的是,否则我们将需要一个用于 `env` 的 `env`。:) (3认同)
  • 为什么我们不能使用`#!python`? (3认同)

小智 24

雅各布的回答很好地解释了这一点。不过还有一点我想提一下。

/usr/bin/env/在 python 中使用还有一个目的。由于 python 支持虚拟环境,使用/usr/bin/env python将确保您的脚本在虚拟环境中运行,如果您在其中的话。而,/usr/bin/python将在虚拟环境之外运行。


小智 7

除了上面给出的答案,使用/usr/bin/env允许你的 Python 安装在非标准的地方,只要你PATH设置正确,脚本将在任何具有/usr/bin/env. 这包括任何现代版本的 Linux 和 OS/X。