繁体   English   中英

我应该在 Python 脚本中输入 #, (shebang) 吗? 应该采取什么形式

[英]Should I put #! (shebang) in Python scripts, and what form should it take?

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

#!/usr/bin/env python 

或者

#!/usr/local/bin/python

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

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

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

(默认为版本 3.latest) Python 3脚本的正确用法是:

#!/usr/bin/env python3

(默认为版本 2.latest) Python 2脚本的正确用法是:

#!/usr/bin/env python2

不应使用以下内容(除非您正在编写与 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"

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

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

我应该把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 - 类 Unix 系统上的“python”命令

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

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

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

#!/usr/bin/python2.7

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

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

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

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

有时,如果答案不是很清楚(我的意思是,你不能,如果是或否决定),那么它没有太大的关系,并且直到答案明确的,你可以忽视的问题。

#! 唯一的目的是启动脚本。 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 的系统中使用 execute 标志类似的行为。

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

即使您没有 shebang 声明符,这也将起作用。

为什么第一个更“可移植”是因为/usr/bin/env包含您的PATH声明,该声明说明了系统可执行文件所在的所有目的地。

注意:Tornado 不严格使用 shebang,Django 也严格不使用。 它因您执行应用程序主要功能的方式而异。

另外:它不随 Python 变化。

当我最近在 Windows 7 上安装 Python 3.6.1 时,它还安装了 Python Launcher for Windows,它应该可以处理 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 行处理如上所述。

如果您安装了不同的模块并且需要使用特定的 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

答:仅当您打算将其设为命令行可执行脚本时。

这是程序:

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

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

对于打算从命令行执行的文件,我建议

#! /usr/bin/env python3

否则你真的不需要shebang(尽管它当然没有害处)。

绝对与逻辑路径:

这实际上是关于 Python 解释器的路径应该是绝对的还是逻辑的/usr/bin/env )就可移植性而言的问题。

遇到这个和谈论这个问题在一般的方式,而不支持其他证明堆栈网站其他的答案,我已经上了unix.stackexchange.com过这个问题进行了一些真的,真的,颗粒测试和分析。 我不会在此处粘贴该答案,而是将那些对该答案的比较分析感兴趣的人指出:

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

作为一名 Linux 工程师,我的目标始终是为我的开发人员客户提供最合适、最优化的主机,因此 Python 环境问题是我真正需要一个可靠答案的问题。 测试后我的观点是,she-bang 中的逻辑路径是 (2) 选项中更好的。

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

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

如果你想让你的文件可执行,你必须在你的脚本中添加 shebang 行。

#!/usr/bin/env python3 

是更好的选择,因为它不依赖于特定的 linux 发行版,但可以用于几乎所有的 linux 发行版,因为它从环境变量中寻找 python3 路径,这对于不同的 linux 发行版是不同的。

然而

#!/usr/local/bin/python3 

将是 python3 的发行版特定路径,如果在此路径上找不到 python3,它将不起作用,并且可能导致开发人员在从一个发行版迁移到另一个 linux 发行版时产生混淆和歧义。

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

#!/usr/bin/env python 

或者

#!/usr/local/bin/python

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

注意:龙卷风项目使用shebang。 另一方面, Django项目则没有。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM