在 shebang 中使用“#!/usr/bin/env python”而不是仅仅调用“#!python”解释器有什么好处?
What is the advantage of "#!/usr/bin/env python" in the shebang rather than just calling the "#!python" interpreter?
我了解启动 python 脚本的区别:
#!/usr/bin/env python
或
#!/usr/bin/python
据我了解,就像我们在 shell 中执行的那样,只执行 python,所以它会在 $PATH
中查找。第二个不是固定路径,这带来的不便在于,在不同的系统中,python 解释器可能位于另一条路径中。
我的问题是,为什么我们需要 env
?为什么我们可以这样做:
#!python
这在我的电脑上工作得很好吗?有理由更喜欢打电话给 env
吗?
简答:
这取决于shell。在 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、其他?)这里至少是我的 OS( 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 上,此行可用于 select 显式 python2 或 python3。
Windows 使用文件类型关联来确定为哪个后缀调用哪个可执行文件。对于 .py 文件(安装了 python 3.x),这通常是 py.exe,它是位于系统路径中的可执行文件,它只会调用 python 解释器。根据安装的版本、shebang 行和环境变量,这可能表示 virtualenv
附录:
第一行由 shell 解释,或者在 windows 情况下由 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) 到安装程序指定的路径。
现在,当您 运行 脚本时,它将指向您已经提供的正确路径,而不会受到可能选择错误版本的 运行time PATH 查找的影响。
请注意,#!python
不能按原样使用,尽管出于各种原因,它 可能 适合您。这是一种确保脚本获得正确解释器的固定绝对路径的方法。 #!/usr/bin/python
也 受安装时替换的影响,因此可以作为可用的默认值。
我了解启动 python 脚本的区别:
#!/usr/bin/env python
或
#!/usr/bin/python
据我了解,就像我们在 shell 中执行的那样,只执行 python,所以它会在 $PATH
中查找。第二个不是固定路径,这带来的不便在于,在不同的系统中,python 解释器可能位于另一条路径中。
我的问题是,为什么我们需要 env
?为什么我们可以这样做:
#!python
这在我的电脑上工作得很好吗?有理由更喜欢打电话给 env
吗?
简答:
这取决于shell。在 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、其他?)这里至少是我的 OS( 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 上,此行可用于 select 显式 python2 或 python3。 Windows 使用文件类型关联来确定为哪个后缀调用哪个可执行文件。对于 .py 文件(安装了 python 3.x),这通常是 py.exe,它是位于系统路径中的可执行文件,它只会调用 python 解释器。根据安装的版本、shebang 行和环境变量,这可能表示 virtualenv
附录: 第一行由 shell 解释,或者在 windows 情况下由 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) 到安装程序指定的路径。
现在,当您 运行 脚本时,它将指向您已经提供的正确路径,而不会受到可能选择错误版本的 运行time PATH 查找的影响。
请注意,#!python
不能按原样使用,尽管出于各种原因,它 可能 适合您。这是一种确保脚本获得正确解释器的固定绝对路径的方法。 #!/usr/bin/python
也 受安装时替换的影响,因此可以作为可用的默认值。