关于shell:我应该在python脚本中放 #!,应该采用什么形式?

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

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

1
#!/usr/bin/env python

1
#!/usr/local/bin/python

这些东西同样可以携带吗?哪种形式最常用?

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


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

python 3脚本的正确用法是:

1
#!/usr/bin/env python3

默认为3.latest版本。对于python 2.7.最新使用python2代替python3

不应使用以下代码(除了编写与python 2.x和3.x兼容的代码的罕见情况):

1
#!/usr/bin/env python

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

另外,不要使用:

1
#!/usr/local/bin/python

"python may be installed at /usr/bin/python or /bin/python in those
cases, the above #! will fail."

——"啊!/usr/bin/env python"vs"!/usr/local/bin/python"


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

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


Should I put the shebang in my Python scripts?

在python脚本中放入shebang以指示:

  • 此模块可以作为脚本运行
  • 它是只能在python2、python3上运行,还是与python2/3兼容
  • 在posix上,如果您希望直接运行脚本而不显式调用python可执行文件,则有必要

Are these equally portable? Which form is used most?

如果您手动编写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,则shebang是指向特定python可执行文件(如#!/usr/local/bin/python)的路径(注意:不应手动写入后一类中的路径)。

要选择是否应在shebang中使用pythonpython2python3,请参见pep 394-类Unix系统上的"python"命令:

  • ... python should be used in the shebang line only for scripts that are
    source compatible with both Python 2 and 3.

  • in preparation for an eventual change in the default version of
    Python, Python 2 only scripts should either be updated to be source
    compatible with Python 3 or else to use python2 in the shebang line.


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

1
#!/usr/bin/python2.7

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

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

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


如果脚本要可执行,则应添加shebang。您还应该使用一个安装软件来安装脚本,该软件将shebang修改为正确的版本,这样它就可以在目标平台上工作。例如distutils和distribute。


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

即使没有shebang声明器,这也可以工作。

第一个更"可移植"的原因是,/usr/bin/env包含了您的PATH声明,它说明了您的系统可执行文件所在的所有目的地。

注意:Tornado不严格使用shebangs,django严格不使用shebangs。它随应用程序的主要功能的执行方式而变化。

另外:它不会随python而变化。


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

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


当我最近在Windows7上安装了python 3.6.1时,它还安装了用于windows的python launcher for windows,它应该处理shebang行。但是,我发现python启动程序并没有这样做:shebang行被忽略,并且总是使用python 2.7.13(除非我使用py-3执行脚本)。

为了解决这个问题,我必须编辑Windows注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.File\shell\open\command。这仍然有价值

1
"C:\Python27\python.exe""%1" %*

从我以前的python 2.7安装。我将此注册表项值修改为

1
"C:\Windows\py.exe""%1" %*

而python启动程序shebang行的处理工作如上所述。


答:只有当您计划将其设置为命令行可执行脚本时。程序如下:

首先验证要使用的正确shebang字符串:

1
which python

从中获取输出并添加它(使用shebang!)在第一行。

在我的系统上,它的响应如下:

1
2
$which python
/usr/bin/python

所以你的shebang看起来像:

1
#!/usr/bin/python

保存之后,它仍将像以前一样运行,因为Python将第一行视为注释。

1
python filename.py

要使其成为命令,请复制它以删除.py扩展名。

1
cp filename.py filename

告诉文件系统这将是可执行的:

1
chmod +x filename

要测试它,请使用:

1
./filename

最佳实践是将其移动到$path中的某个位置,这样您只需要键入文件名本身。

1
sudo cp filename /usr/sbin

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


首先使用

1
which python

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

这个输出可以是

1
/usr/bin/python

1
/bin/python

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

概括起来,我们可以使用:

1
#!/usr/bin/env

1
#!/bin/env