我应该把 shebang 放在我的 Python 脚本中吗?以什么形式?
#!/usr/bin/env python
或者
#!/usr/local/bin/python
这些是否同样便携?哪种形式使用最多?
注意:tornado 项目使用 shebang。另一方面,Django 项目没有。
#!/usr/bin/python
与第一个选项相比如何?我在很多示例代码中都看到了这一点。编辑:也许这就是答案.. stackoverflow.com/a/2429517/1156245
/usr/bin/env python
显式,表示“使用环境的默认 python”,允许 pip/user/OS/local admin/virtualenv 通过 $PATH
选择一个,而/usr/bin/python
强制操作系统选择的 python
任何脚本中的 shebang 行决定了脚本是否能够像独立可执行文件一样执行,而无需事先在终端中键入 python
或在文件管理器中双击它(如果配置正确)。这不是必需的,但通常放在那里,所以当有人看到在编辑器中打开的文件时,他们会立即知道他们在看什么。但是,您使用哪条 shebang 行 很重要。
Python 3 脚本(默认为版本 3.latest)的正确用法是:
#!/usr/bin/env python3
Python 2 脚本的正确用法(默认为 2.latest 版本)是:
#!/usr/bin/env python2
不应使用以下内容(除了您正在编写与 Python 2.x 和 3.x 兼容的代码的极少数情况):
#!/usr/bin/env python
在 PEP 394 中给出这些建议的原因是 python
可以引用不同系统上的 python2
或 python3
。
另外,不要使用:
#!/usr/local/bin/python
“在这些情况下,python 可能安装在 /usr/bin/python 或 /bin/python 中,上面的 #! 将失败。”
——"#!/usr/bin/env python" vs "#!/usr/local/bin/python"
这真的只是口味问题。添加 shebang 意味着人们可以根据需要直接调用脚本(假设它被标记为可执行文件);省略它只是意味着必须手动调用 python
。
无论哪种方式,运行程序的最终结果都不会受到影响;这只是手段的选择。
chmod a+x [your-script].py
之类的东西应该使它可执行,然后您可以在 shell 中调用 ./[your-script.py]
。
if __name__ == "__main__":
的用途吗?
我应该把 shebang 放在我的 Python 脚本中吗?
将 shebang 放入 Python 脚本中以指示:
这个模块可以作为脚本运行
是否只能在 python2、python3 上运行,还是兼容 Python 2/3
在 POSIX 上,如果您想直接运行脚本而不显式调用 python 可执行文件,则有必要
这些是否同样便携?哪种形式使用最多?
如果您手动编写 shebang,则始终使用 #!/usr/bin/env python
,除非您有特定理由不使用它。即使在 Windows(Python 启动器)上也能理解这种形式。
注意:已安装 脚本应使用特定的 python 可执行文件,例如 /usr/bin/python
或 /home/me/.virtualenvs/project/bin/python
。如果您在 shell 中激活 virtualenv,如果某些工具损坏,那就不好了。幸运的是,在大多数情况下,正确的 shebang 是由 setuptools
或您的分发包工具自动创建的(在 Windows 上,setuptools
可以自动生成包装器 .exe
脚本)。
换句话说,如果脚本在源检出中,那么您可能会看到 #!/usr/bin/env python
。如果已安装,则 shebang 是特定 python 可执行文件的路径,例如 #!/usr/local/bin/python
(注意:您不应手动编写后一类的路径)。
要选择是否应在 shebang 中使用 python
、python2
或 python3
,请参阅 PEP 394 - The "python" Command on Unix-Like Systems:
... python 应该仅用于与 Python 2 和 3 源代码兼容的脚本的 shebang 行中。为了准备最终更改 Python 的默认版本,仅 Python 2 的脚本应该更新为与源代码兼容使用 Python 3 或在 shebang 行中使用 python2。
#!/usr/bin/env python
本身是否有 PEP?
#!/usr/bin/env python
。请不要建议“始终使用”#!/usr/bin/env python
。在 99% 的情况下,这是错误的做法(您在答案中包含的原因)。
如果你有多个 Python 版本,并且脚本需要在特定版本下运行,she-bang 可以确保在直接执行脚本时使用正确的版本,例如:
#!/usr/bin/python2.7
请注意,脚本仍然可以通过完整的 Python 命令行或通过导入运行,在这种情况下,she-bang 将被忽略。但是对于直接运行的脚本,这是使用 she-bang 的一个很好的理由。
#!/usr/bin/env python
通常是更好的方法,但这有助于特殊情况。
通常最好建立一个 Python 虚拟环境,在这种情况下,通用 #!/usr/bin/env python
将为 virtualenv 识别正确的 Python 实例。
which
的结果将为您提供一个有效的字符串,句号。您无需担心任何胆量即可使用它。
shebang 的目的是让脚本在您想从 shell 执行脚本时识别解释器类型。大多数情况下,并非总是如此,您通过在外部提供解释器来执行脚本。示例用法:python-x.x script.py
即使您没有 shebang 声明符,这也将起作用。
为什么第一个更“便携”是因为,/usr/bin/env
包含您的 PATH
声明,它说明了您的系统可执行文件所在的所有目的地。
注意:Tornado 不严格使用 shebang,而 Django 严格不使用。它因您执行应用程序的主要功能的方式而异。
另外:它不会随 Python 变化。
如果脚本是可执行的,您应该添加一个 shebang。您还应该使用将 shebang 修改为正确的安装软件来安装脚本,以便它可以在目标平台上运行。这方面的例子是 distutils 和 Distribute。
which
的结果将自动选择系统命令等使用的默认值。它是通用的,系统会引导它正确安装。
有时,如果答案不是很清楚(我的意思是你无法决定是或否),那也没关系,你可以忽略问题,直到答案清楚为止。
#!
的唯一用途是启动脚本。 Django 自己加载源代码并使用它们。它永远不需要决定应该使用什么解释器。这样,#!
在这里实际上没有意义。
一般如果是模块,不能作为脚本使用,则不需要使用#!
。另一方面,模块源通常包含 if __name__ == '__main__': ...
,并至少对功能进行了一些简单的测试。然后 #!
再次有意义。
使用 #!
的一个很好的原因是当您同时使用 Python 2 和 Python 3 脚本时——它们必须由不同版本的 Python 解释。这样,您必须记住手动启动脚本时必须使用的 python
(没有内部的 #!
)。如果您有这些脚本的混合,最好使用内部的 #!
,使其可执行,然后将它们作为可执行文件启动(chmod ...)。
使用 MS-Windows 时,#!
没有意义——直到最近。 Python 3.3 引入了一个 Windows Python 启动器(py.exe 和 pyw.exe),它读取 #!
行,检测已安装的 Python 版本,并使用正确或明确需要的 Python 版本。由于扩展可以与程序相关联,因此您可以在 Windows 中获得与基于 Unix 的系统中的执行标志类似的行为。
当我最近在 Windows 7 上安装 Python 3.6.1 时,它还安装了适用于 Windows 的 Python Launcher,它应该可以处理 shebang 行。但是,我发现 Python Launcher 并没有这样做:shebang 行被忽略,并且始终使用 Python 2.7.13(除非我使用 py -3 执行脚本)。
要解决此问题,我必须编辑 Windows 注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.File\shell\open\command
。这仍然有价值
"C:\Python27\python.exe" "%1" %*
来自我早期的 Python 2.7 安装。我将此注册表项值修改为
"C:\Windows\py.exe" "%1" %*
并且 Python Launcher shebang 行处理如上所述。
答:仅当您计划将其设为命令行可执行脚本时。
这是程序:
首先验证要使用的正确 shebang 字符串:
which python
从中获取输出并在第一行添加它(使用 shebang #!)。
在我的系统上,它的响应如下:
$which python
/usr/bin/python
所以你的 shebang 看起来像:
#!/usr/bin/python
保存后,它仍会像以前一样运行,因为 python 会将第一行视为注释。
python filename.py
要使其成为命令,请将其复制以删除 .py 扩展名。
cp filename.py filename
告诉文件系统这将是可执行的:
chmod +x filename
要对其进行测试,请使用:
./filename
最佳做法是将其移动到 $PATH 中的某个位置,因此您只需要输入文件名本身即可。
sudo cp filename /usr/sbin
这样它就可以在任何地方工作(文件名前没有 ./)
如果您安装了不同的模块并且需要使用特定的 python 安装,那么 shebang 一开始似乎受到限制。但是,您可以执行以下技巧,以允许首先将 shebang 作为 shell 脚本调用,然后选择 python。这是非常灵活的imo:
#!/bin/sh
#
# Choose the python we need. Explanation:
# a) '''\' translates to \ in shell, and starts a python multi-line string
# b) "" strings are treated as string concat by python, shell ignores them
# c) "true" command ignores its arguments
# c) exit before the ending ''' so the shell reads no further
# d) reset set docstrings to ignore the multiline comment code
#
"true" '''\'
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3
if [ -x $PREFERRED_PYTHON ]; then
echo Using preferred python $PREFERRED_PYTHON
exec $PREFERRED_PYTHON "$0" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
echo Using alternative python $ALTERNATIVE_PYTHON
exec $ALTERNATIVE_PYTHON "$0" "$@"
else
echo Using fallback python $FALLBACK_PYTHON
exec python3 "$0" "$@"
fi
exit 127
'''
__doc__ = """What this file does"""
print(__doc__)
import platform
print(platform.python_version())
或者更好的是,也许是为了促进跨多个 python 脚本的代码重用:
#!/bin/bash
"true" '''\'; source $(cd $(dirname ${BASH_SOURCE[@]}) &>/dev/null && pwd)/select.sh; exec $CHOSEN_PYTHON "$0" "$@"; exit 127; '''
然后 select.sh 有:
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3
if [ -x $PREFERRED_PYTHON ]; then
CHOSEN_PYTHON=$PREFERRED_PYTHON
elif [ -x $ALTERNATIVE_PYTHON ]; then
CHOSEN_PYTHON=$ALTERNATIVE_PYTHON
else
CHOSEN_PYTHON=$FALLBACK_PYTHON
fi
这确实是一个关于 Python 解释器的路径在可移植性方面应该是absolute 还是 logical (/usr/bin/env
) 的问题。
在彻底测试行为之后,我的观点是,she-bang 中的逻辑路径是两个选项中更好的一个。
作为一名 Linux 工程师,我的目标始终是为我的开发者客户提供最合适、最优化的主机,因此 Python 环境问题是我真正需要一个可靠答案的问题。在此站点和其他 Stack Overflow 站点上遇到其他答案,这些站点以一般方式讨论该问题而没有支持证明,我在 Unix.SE 上就这个问题执行了一些真的 granular testing & analysis。
对于打算从命令行执行的文件,我建议
#! /usr/bin/env python3
否则你不需要shebang(当然它没有害处)。
如果您使用 pyenv 之类的虚拟环境,最好编写 #!/usr/bin/env python
pyenv 设置将控制哪个版本的 python 以及从哪个文件位置开始运行您的脚本。
如果已知您的代码是特定于版本的,那么如果您在 shebang 中指定预期版本,它将帮助其他人找出您的脚本在他们的环境中不运行的原因。
如果要使文件可执行,则必须将 shebang 行添加到脚本中。
#!/usr/bin/env python3
是更好的选择,因为它不依赖于特定的 Linux 发行版,但可以在几乎所有 linux 发行版上使用,因为它从环境变量中寻找 python3 路径,这对于不同的 Linux 发行版是不同的。
然而
#!/usr/local/bin/python3
将是 python3 的发行版特定路径,如果在此路径上找不到 python3,则该路径将不起作用,并且在从一个发行版迁移到另一个 Linux 发行版时,可能会导致开发人员混淆和模棱两可。
先用
which python
这会将输出作为我的 python 解释器(二进制)所在的位置。
该输出可以是任何诸如
/usr/bin/python
或者
/bin/python
现在适当地选择shebang线并使用它。
为了概括,我们可以使用:
#!/usr/bin/env
或者
#!/bin/env
#!/usr/bin/env
为您做出正确的选择。
which
命令的原因 - 它会为您的特定系统返回正确的字符串。
which python
并更改脚本
env
将总是在/usr/bin/
中找到,它的工作是使用PATH
定位 bin(如 python)。不管怎么安装python,它的路径都会添加到这个变量中,env
会找到它(如果没有,python没有安装)。这就是env
的工作,这就是它存在的全部原因。这是提醒环境的东西(设置环境变量,包括安装路径和包含路径)。人们一直都明白,这个命令只有在总是在同一个地方找到时才能起作用。这只是给定的#!/usr/bin/env python3
在 window10 中不起作用。#!/usr/bin/env python
适用于 Windows10 和ubuntupython
。建议显式使用python2
或python3
。有包python-is-python2
和python-is-python3
再次添加python
命令。 Python 2 自 2020 年 1 月 1 日起就无人维护,因此必须迁移到 Python 3。 wiki.debian.org/Python#!/usr/bin/env python3
在通过 py.exe 使用时应该可以工作。 docs.python.org/3/using/windows.html#shebang-lines docs.microsoft.com/en-us/windows/python/faqs#what-is-py-exe-