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

2024-12-02 08:41:00
admin
原创
193
摘要:问题描述:我应该将 shebang 放入 Python 脚本中吗?以什么形式?#!/usr/bin/env python 或者#!/usr/local/bin/python 这些是否同样便携?哪种形式最常用?注意:tornado项目使用 shebang。而Django项目则不使用。解决方案 1:任何脚本中的...

问题描述:

我应该将 shebang 放入 Python 脚本中吗?以什么形式?

#!/usr/bin/env python 

或者

#!/usr/local/bin/python

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

注意:tornado项目使用 shebang。而Django项目则不使用。


解决方案 1:

任何脚本中的 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可以引用python2python3位于不同的系统上。

此外,请勿使用:

#!/usr/local/bin/python

“python 可能安装在 /usr/bin/python 或 /bin/python 在这些情况下,上述 #! 将失败。”

― “#!/usr/bin/env python” 与 “#!/usr/local/bin/python”

解决方案 2:

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

无论如何,运行程序的最终结果都不会受到影响;这只是方法的选择。

解决方案 3:

我应该把 shebang 放入我的 Python 脚本中吗?

将 shebang 放入 Python 脚本中以指示:

  • 该模块可以作为脚本运行

  • 它是否只能在 python2、python3 上运行,或者是否兼容 Python 2/3

  • 在 POSIX 上,如果你想直接运行脚本而不python显式调用可执行文件,则有必要

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

如果您手动编写 shebang,则请始终使用#!/usr/bin/env python(或#!/usr/bin/env python2/ #!/usr/bin/env python3,见下文),除非您有特殊原因不使用它。即使在 Windows(Python 启动器)上也可以理解此形式。

注意:已安装的脚本应使用特定的 Python 可执行文件,例如/usr/bin/python/home/me/.virtualenvs/project/bin/python。如果在 shell 中激活虚拟环境,某些工具会崩溃,那就糟糕了。幸运的是,在大多数情况下,正确的 shebang 会由或您的分发包工具自动创建setuptools(在 Windows 上,setuptools可以自动生成包装器.exe脚本)。

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

要选择是否应在 shebang 中使用 、 或 ,请参阅pythonPEP python2394 - 类 Unix 系统上的“python”命令:python3

  • ...python应该只在与 Python 2 和 3 源兼容的脚本的 shebang 行中使用。

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

解决方案 4:

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

#!/usr/bin/python2.7

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

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

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

解决方案 5:

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

即使您没有 shebang 声明器,这也会起作用。

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

注意:Tornado 并不严格使用 shebang,Django 也不严格使用。这取决于您执行应用程序主函数的方式。

另外:它不会因 Python 而变化。

解决方案 6:

有时候,如果答案不是很清楚(我的意思是你无法决定是或否),那么这就不会太重要了,你可以忽略这个问题,直到答案明确为止。

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

解决方案 7:

如果脚本旨在可执行,则应添加 shebang。您还应使用安装软件安装脚本,该软件会将 shebang 修改为正确的内容,以便其可以在目标平台上运行。distutils 和 Distribute 就是此类示例。

解决方案 8:

最近我在 Windows 7 上安装 Python 3.6.1 时,还安装了适用于 Windows 的 Python Launcher,它应该可以处理 shebang 行。但是,我发现 Python Launcher 并没有这样做:shebang 行被忽略,并且始终使用 Python 2.7.13(除非我使用 py -3 执行脚本)。

为了解决这个问题,我必须编辑 Windows 注册表项HKEY_LOCAL_MACHINESOFTWAREClassesPython.Fileshellopencommand。这仍然具有值

"C:Python27python.exe" "%1" %*

来自我之前的 Python 2.7 安装。我修改了这个注册表项值以

"C:Windowspy.exe" "%1" %*

并且 Python Launcher shebang 行处理工作如上所述。

解决方案 9:

答案:只有当您计划将其制作成命令行可执行脚本时才会这样。

具体步骤如下:

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

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

解决方案 10:

如果您安装了不同的模块,并且需要使用特定的 Python 安装,那么 Shebang 一开始似乎会受到限制。但是,您可以像下面这样使用技巧,让 Shebang 首先作为 shell 脚本调用,然后选择 Python。在我看来,这非常灵活:

#!/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

解决方案 11:

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

在彻底测试了该行为之后,我的观点是,she-bang 中的逻辑路径是两种选择中更好的一种

作为一名 Linux 工程师,我的目标始终是为我的开发人员客户提供最合适、最优化的主机,因此 Python 环境问题确实是一个我需要一个可靠答案的问题。我在这个和其他 Stack Overflow 网站上遇到了其他答案,它们以一般性的方式讨论了这个问题,但没有提供支持性证据,因此我在 Unix.SE 上对这个问题进行了一些非常 细致的测试和分析。

解决方案 12:

对于那些可以从命令行执行的文件,我建议

#! /usr/bin/env python3

否则,您不需要shebang(当然,它不会造成任何伤害)。

解决方案 13:

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

如果已知您的代码是特定于版本的,那么如果您在 shebang 中指定预期版本,它将帮助其他人找到您的脚本在他们的环境中无法正常运行的原因。

解决方案 14:

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

#!/usr/bin/env python3 

是更好的选择,因为它不会依赖于特定的 Linux 发行版,而是可以在几乎所有的 Linux 发行版上使用,因为它从环境变量中搜索 python3 路径,而不同的 Linux 发行版的路径是不同的。

然而

#!/usr/local/bin/python3 

将是 python3 的发行版特定路径,如果在此路径上找不到 python3,它将不起作用,并且可能会导致开发人员在从一个 Linux 发行版迁移到另一个发行版时感到困惑和模糊。

解决方案 15:

首先使用

which python

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

此输出可以是任何输出,例如

/usr/bin/python

或者

/bin/python

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

为了概括,我们可以使用:

#!/usr/bin/env

或者

#!/bin/env
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2560  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1552  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   1  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   2  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   3  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用