我应该放#! (shebang)在Python脚本中,应该采用什么形式?

时间:2011-08-02 06:35:43

标签: python shell python-3.x shebang

我应该把shebang放在我的Python脚本中吗?以什么形式?

#!/usr/bin/env python 

#!/usr/local/bin/python

这些是否同样便携?哪种形式最常用?

注意: tornado项目使用shebang。另一方面,Django项目没有。

13 个答案:

答案 0 :(得分:888)

任何脚本中的shebang行都会确定脚本能够像独立可执行文件一样执行,而无需事先在终端中键入python,或者在文件管理器中双击它(如果配置正确)。没有必要,但通常放在那里,所以当有人看到在编辑器中打开文件时,他们立即知道他们正在看什么。但是,使用哪个shebang系列 IS 很重要。

正确 Python 3脚本的用法是:

#!/usr/bin/env python3

默认为版本3.latest。对于Python 2.7.latest,使用python2代替python3

不应使用以下 (除了极少数情况下您编写的代码与Python 2.x和3.x兼容):

#!/usr/bin/env python

PEP 394中提出的这些建议的原因是python可以在不同系统上引用python2python3。它目前在大多数发行版中引用python2,但这可能会在某些时候发生变化。

另外,请勿使用:

#!/usr/local/bin/python
  

“python可以安装在/ usr / bin / python或/ bin / python中   案例,以上#!会失败。“

- "#!/usr/bin/env python" vs "#!/usr/local/bin/python"

答案 1 :(得分:67)

这真的只是品味问题。添加shebang意味着人们可以根据需要直接调用脚本(假设它被标记为可执行文件);省略它只是意味着必须手动调用python

运行程序的最终结果不受任何影响;它只是手段的选择。

答案 2 :(得分:25)

  

我应该把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,一些工具会中断,这很糟糕。幸运的是,大多数情况下setuptools或您的分发包工具会自动创建正确的shebang(在Windows上,setuptools可以自动生成包装.exe脚本。)

换句话说,如果脚本在源检出中,那么您可能会看到#!/usr/bin/env python。如果已安装,则shebang是特定python可执行文件的路径,例如#!/usr/local/bin/python(注意:您不应手动编写后一类别的路径)。

要选择是否应在shebang中使用pythonpython2python3,请参阅PEP 394 - The "python" Command on Unix-Like Systems

  
      
  • ... python应仅用于shebang行中的脚本   源代码兼容Python 2和3。

  •   
  • 准备最终更改默认版本   只应将Python,Python 2脚本更新为源代码   与Python 3兼容,或者在shebang行中使用python2

  •   

答案 3 :(得分:15)

如果你有多个版本的Python并且脚本需要在特定版本下运行,那么她可以确保在直接执行脚本时使用正确的脚本,例如:

#!/usr/bin/python2.7

请注意,脚本仍然可以通过完整的Python命令行运行,或者通过导入运行,在这种情况下,将忽略she-bang。但是对于直接运行的脚本,这是使用she-bang的正当理由。

#!/usr/bin/env python通常是更好的方法,但这有助于处理特殊情况。

通常最好建立一个Python虚拟环境,在这种情况下,通用#!/usr/bin/env python将为virtualenv识别正确的Python实例。

答案 4 :(得分:10)

如果脚本是可执行的,则应添加一个shebang。您还应该使用安装软件安装脚本,该软件将shebang修改为正确的内容,以便它可以在目标平台上运行。这方面的例子是distutils和Distribute。

答案 5 :(得分:9)

shebang的目的是让脚本在您想要从shell执行脚本时识别解释器类型。 大多数情况下,并非总是如此,您通过外部提供解释程序来执行脚本。 用法示例:python-x.x script.py

即使你没有一个shebang声明者,这也会有用。

为什么第一个更容易携带"是因为,/usr/bin/env包含您的PATH声明,该声明会说明您的系统可执行文件所在的所有目的地。

注意:龙卷风并不严格使用shebangs,Django严格禁止使用。它取决于您执行应用程序的主要功能。

另外:它与Python不同。

答案 6 :(得分:7)

有时候,如果答案不是很清楚(我的意思是你不能决定是或否),那么它并不重要,你可以忽略这个问题,直到答案 清除

#!用于启动脚本。 Django自己加载源并使用它们。它永远不需要决定应该使用哪种解释器。这样,#!实际上没有任何意义。

通常,如果它是一个模块而不能用作脚本,则无需使用#!。另一方面,模块源通常包含if __name__ == '__main__': ...,至少对功能进行了一些简单的测试。然后#!再次有意义。

使用#!的一个很好的理由是当你同时使用Python 2和Python 3脚本时 - 它们必须由不同版本的Python解释。这样,您必须记住手动启动脚本时必须使用的python(内部没有#!)。如果你有这些脚本的混合,最好在里面使用#!,使它们可执行,并将它们作为可执行文件启动(chmod ...)。

使用MS-Windows时,#!没有任何意义 - 直到最近。 Python 3.3引入了一个Windows Python Launcher(py.exe和pyw.exe),它读取#!行,检测已安装的Python版本,并使用正确或明确需要的Python版本。由于扩展可以与程序相关联,因此在Windows中可以获得与基于Unix的系统中的执行标志类似的行为。

答案 7 :(得分:2)

当我最近在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线处理如上所述。

答案 8 :(得分:1)

答案:只有在您计划将其设为命令行可执行脚本时才会这样。

以下是程序:

首先验证要使用的正确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

这样它可以在任何地方工作(没有文件名之前的./)

答案 9 :(得分:1)

如果您安装了其他模块,并且需要使用特定的 python install,然后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 $ALTERNATIVE_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

答案 10 :(得分:0)

绝对路径与逻辑路径:

这实际上是关于Python解释器的路径是 绝对 还是 逻辑 的问题( /usr/bin/env)。

在此和其他Stack网站上遇到了其他问题,这些问题在没有证据支持的情况下以一般方式讨论了该问题,因此我对这个问题进行了一些真正的 REALLY 粒度测试和分析。 unix.stackexchange.com 。与其在此处粘贴答案,不如将那些对比较分析感兴趣的人指向该答案:

https://unix.stackexchange.com/a/566019/334294

作为一名Linux工程师,我的目标始终是为我的开发人员客户端提供最合适,最优化的主机,因此,我确实需要一个可靠的解决方案来解决Python环境问题。测试后,我的看法是,在(2-)选项中,she-bang中的 逻辑 路径更好。

答案 11 :(得分:0)

如果你使用像 pyenv 这样的虚拟环境,最好写 #!/usr/bin/env python pyenv 设置将控制哪个版本的 python 以及从哪个文件位置开始运行您的脚本。

如果已知您的代码是特定于版本的,那么如果您在 shebang 中指定预期版本,它将帮助其他人找出您的脚本在他们的环境中不起作用的原因。

答案 12 :(得分:-3)

先使用

which python

这将输出作为我的python解释器(二进制)所在的位置。

此输出可以是

之类的输出
/usr/bin/python

/bin/python

现在适当选择shebang线并使用它。

概括我们可以使用:

#!/usr/bin/env

#!/bin/env