"#!/usr/bin/env python"在舍邦而不是仅仅打电话给"#!python"翻译有什么好处?

  • 本文关键字:python 翻译 打电话 env bin usr python shebang
  • 更新时间 :
  • 英文 :


我理解启动python脚本之间的区别,例如:

#!/usr/bin/env python

#!/usr/bin/python

据我了解,只需像在 shell 中那样执行 python,因此它看起来$PATH.第二个不是固定路径,这很不方便,在不同的系统中,python解释器可能位于另一条路径中。

我的问题是,为什么我们需要env?为什么我们可以做:

#!python

这在我的电脑中工作得很好?有理由更喜欢打电话给env吗?

简短回答:这取决于外壳。 在 bash 中,#!python将被忽略,您必须使用#!/usr/bin/env python. 另一方面,zsh似乎能够处理#!python

长答案(对于bash(:

假设你的 Python 文件名为"tst.py" 并有以下内容

#!python
import sys
print(sys.executable, sys.version)

然后您可以随时输入

python tst.py

第一行完全无关紧要,甚至没有看过。

但是,如果您执行以下操作(例如在 Linux 上(

chmod +x tst.py
./tst.py

然后查看第一行以确定应该使用哪个解释器(bash,perl,python,其他东西?(,这里至少对于我的操作系统(ubuntu(和我的shell(bash(需要可执行文件名称的绝对路径(例如/bin/bash/bin/python/usr/bin/env(

如果我在我的 ubuntu 机器上调用 ./tst.py,我会得到

bash: ./tst.py: python: bad interpreter: No such file or directory

特殊情况下Windows,当键入 tst.py 或单击python脚本时。 如果你在Windows上,会查看该行,但即使它是错误的,也会使用默认的python解释器。例如,在Windows上,此行可用于显式选择python2或python3。 Windows 使用文件类型关联来确定要为哪个后缀调用哪个可执行文件。对于.py文件(安装了Python 3.x(,这通常是py.exe它是位于系统路径中的可执行文件,它只会调用python解释器。根据安装的版本,Shebang 线和环境变量,这可能表示虚拟环境

补遗: 第一行由 shell 解释,在窗口情况下由 py.exe 解释。

似乎bash需要绝对路径来命令,而zsh也接受相对路径。

所以只为 zsh

#!python

工作得很好,而bash需要绝对路径,因此使用env命令的技巧

#!/usr/bin/env python

对于应由 cronjob 执行的脚本,最好对 python 可执行文件的路径进行硬编码,因为 PATH 对于 cronjobs 来说是相当简约的,所以最好有类似的东西

#!/usr/bin/python3.5

#!/home/username/myvirtualenv/bin/python

每个 Python脚本都是在编写时考虑特定版本的 Python。如果 shebang 是#!/usr/bin/env python的,则将使用的版本置于单个调用者的控制之下,其PATH可能无法提供正确的版本。

#!/usr/bin/python好一点,因为它将决定权交给了脚本本身。但是,脚本作者不一定知道 Python 的更正版本在您的系统上的位置,因此它仍然可能无法正常工作。

解决方案是在安装模块或脚本时指定系统上的正确位置。此时,Python 安装程序(pip等(会将任何包含单词python的 shebang(#!python是最小的此类 shebang(重写为安装程序指定的路径。

现在,当您运行脚本时,它将指向您已经提供的正确路径,而不受运行时 PATH 查找的约束,该查找可能会选择错误的版本。

请注意,#!python并不意味着按原样使用,尽管出于各种原因它可能对您有用。这是一种确保脚本获得正确解释器的固定、绝对路径的方法。#!/usr/bin/python也会受到安装时替换的影响,因此可以作为可用的默认值。

最新更新