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

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

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

#!/usr/bin/env python 

要么

#!/usr/local/bin/python

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

注:龙卷风项目采用的家当。另一方面, Django项目没有。

Should I put the shebang in my Python scripts? In what form?

#!/usr/bin/env python 

or

#!/usr/local/bin/python

Are these equally portable? Which form is used most?

Note: the tornado project uses the shebang. On the other hand the Django project doesn’t.


回答 0

任何脚本中的shebang行都决定了脚本的执行能力,就像独立的可执行文件一样,无需python事先在终端中键入或在文件管理器中双击(正确配置时)。不必要,但通常放在那里,因此当有人看到在编辑器中打开文件时,他们会立即知道他们在看什么。但是,您使用的家当线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”与“#!/ usr / local / bin / python”

The shebang line in any script determines the script’s ability to be executed like a standalone executable without typing python beforehand in the terminal or when double clicking it in a file manager (when configured properly). It isn’t necessary but generally put there so when someone sees the file opened in an editor, they immediately know what they’re looking at. However, which shebang line you use IS important.

Correct usage for Python 3 scripts is:

#!/usr/bin/env python3

This defaults to version 3.latest. For Python 2.7.latest use python2 in place of python3.

The following should NOT be used (except for the rare case that you are writing code which is compatible with both Python 2.x and 3.x):

#!/usr/bin/env python

The reason for these recommendations, given in PEP 394, is that python can refer either to python2 or python3 on different systems. It currently refers to python2 on most distributions, but that is likely to change at some point.

Also, DO NOT Use:

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


回答 1

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

无论哪种方式,运行该程序的最终结果都不会受到影响。这只是手段的选择。

It’s really just a matter of taste. Adding the shebang means people can invoke the script directly if they want (assuming it’s marked as executable); omitting it just means python has to be invoked manually.

The end result of running the program isn’t affected either way; it’s just options of the means.


回答 2

我应该把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 (注意:您不应手动编写来自后一类别的路径)。

要选择是否应该使用pythonpython2python3在家当,见PEP 394 -在类Unix系统中的“Python”命令

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

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

Should I put the shebang in my Python scripts?

Put a shebang into a Python script to indicate:

  • this module can be run as a script
  • whether it can be run only on python2, python3 or is it Python 2/3 compatible
  • on POSIX, it is necessary if you want to run the script directly without invoking python executable explicitly

Are these equally portable? Which form is used most?

If you write a shebang manually then always use #!/usr/bin/env python unless you have a specific reason not to use it. This form is understood even on Windows (Python launcher).

Note: installed scripts should use a specific python executable e.g., /usr/bin/python or /home/me/.virtualenvs/project/bin/python. It is bad if some tool breaks if you activate a virtualenv in your shell. Luckily, the correct shebang is created automatically in most cases by setuptools or your distribution package tools (on Windows, setuptools can generate wrapper .exe scripts automatically).

In other words, if the script is in a source checkout then you will probably see #!/usr/bin/env python. If it is installed then the shebang is a path to a specific python executable such as #!/usr/local/bin/python (NOTE: you should not write the paths from the latter category manually).

To choose whether you should use python, python2, or python3 in the shebang, see PEP 394 – The “python” Command on Unix-Like Systems:

  • 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.


回答 3

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

#!/usr/bin/python2.7

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

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

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

If you have more than one version of Python and the script needs to run under a specific version, the she-bang can ensure the right one is used when the script is executed directly, for example:

#!/usr/bin/python2.7

Note the script could still be run via a complete Python command line, or via import, in which case the she-bang is ignored. But for scripts run directly, this is a decent reason to use the she-bang.

#!/usr/bin/env python is generally the better approach, but this helps with special cases.

Usually it would be better to establish a Python virtual environment, in which case the generic #!/usr/bin/env python would identify the correct instance of Python for the virtualenv.


回答 4

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

You should add a shebang if the script is intended to be executable. You should also install the script with an installing software that modifies the shebang to something correct so it will work on the target platform. Examples of this is distutils and Distribute.


回答 5

shebang的目的是让脚本在您要从外壳执行脚本时识别解释器类型。通常,并非总是如此,您可以通过从外部提供解释器来执行脚本。用法示例:python-x.x script.py

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

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

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

还:它与Python并没有变化。

The purpose of shebang is for the script to recognize the interpreter type when you want to execute the script from the shell. Mostly, and not always, you execute scripts by supplying the interpreter externally. Example usage: python-x.x script.py

This will work even if you don’t have a shebang declarator.

Why first one is more “portable” is because, /usr/bin/env contains your PATH declaration which accounts for all the destinations where your system executables reside.

NOTE: Tornado doesn’t strictly use shebangs, and Django strictly doesn’t. It varies with how you are executing your application’s main function.

ALSO: It doesn’t vary with 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的系统中的execute标志类似的行为。

Sometimes, if the answer is not very clear (I mean you cannot decide if yes or no), then it does not matter too much, and you can ignore the problem until the answer is clear.

The #! only purpose is for launching the script. Django loads the sources on its own and uses them. It never needs to decide what interpreter should be used. This way, the #! actually makes no sense here.

Generally, if it is a module and cannot be used as a script, there is no need for using the #!. On the other hand, a module source often contains if __name__ == '__main__': ... with at least some trivial testing of the functionality. Then the #! makes sense again.

One good reason for using #! is when you use both Python 2 and Python 3 scripts — they must be interpreted by different versions of Python. This way, you have to remember what python must be used when launching the script manually (without the #! inside). If you have a mixture of such scripts, it is a good idea to use the #! inside, make them executable, and launch them as executables (chmod …).

When using MS-Windows, the #! had no sense — until recently. Python 3.3 introduces a Windows Python Launcher (py.exe and pyw.exe) that reads the #! line, detects the installed versions of Python, and uses the correct or explicitly wanted version of Python. As the extension can be associated with a program, you can get similar behaviour in Windows as with execute flag in Unix-based systems.


回答 7

当我最近在Windows 7上安装Python 3.6.1时,它还安装了Windows的Python启动器,该应用程序应该可以处理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行处理如上所述。

When I installed Python 3.6.1 on Windows 7 recently, it also installed the Python Launcher for Windows, which is supposed to handle the shebang line. However, I found that the Python Launcher did not do this: the shebang line was ignored and Python 2.7.13 was always used (unless I executed the script using py -3).

To fix this, I had to edit the Windows registry key HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.File\shell\open\command. This still had the value

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

from my earlier Python 2.7 installation. I modified this registry key value to

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

and the Python Launcher shebang line processing worked as described above.


回答 8

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

If you have different modules installed and need to use a specific python install, then shebang appears to be limited at first. However, you can do tricks like the below to allow the shebang to be invoked first as a shell script and then choose python. This is very flexible 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())

Or better yet, perhaps, to facilitate code reuse across multiple python scripts:

#!/bin/bash
"true" '''\'; source $(cd $(dirname ${BASH_SOURCE[@]}) &>/dev/null && pwd)/select.sh; exec $CHOSEN_PYTHON "$0" "$@"; exit 127; '''

and then select.sh has:

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

回答 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

这样,它将可以在任何地方使用(文件名前没有./)

Answer: Only if you plan to make it a command-line executable script.

Here is the procedure:

Start off by verifying the proper shebang string to use:

which python

Take the output from that and add it (with the shebang #!) in the first line.

On my system it responds like so:

$which python
/usr/bin/python

So your shebang will look like:

#!/usr/bin/python

After saving, it will still run as before since python will see that first line as a comment.

python filename.py

To make it a command, copy it to drop the .py extension.

cp filename.py filename

Tell the file system that this will be executable:

chmod +x filename

To test it, use:

./filename

Best practice is to move it somewhere in your $PATH so all you need to type is the filename itself.

sudo cp filename /usr/sbin

That way it will work everywhere (without the ./ before the filename)


回答 10

绝对路径与逻辑路径:

关于可移植性,这实际上是一个关于Python解释器的路径是绝对路径还是Logical/usr/bin/env)的问题。

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

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

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

Absolute vs Logical Path:

This is really a question about whether the path to the Python interpreter should be absolute or Logical (/usr/bin/env) in respect to portability.

Encountering other answers on this and other Stack sites which talked about the issue in a general way without supporting proofs, I’ve performed some really, REALLY, granular testing & analysis on this very question on the unix.stackexchange.com. Rather than paste that answer here, I’ll point those interested to the comparative analysis to that answer:

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

Being a Linux Engineer, my goal is always to provide the most suitable, optimized hosts for my developer clients, so the issue of Python environments was something I really needed a solid answer to. My view after the testing was that the logical path in the she-bang was the better of the (2) options.


回答 11

首先使用

which python

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

此输出可以是任何这样的

/usr/bin/python

要么

/bin/python

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

概括地说,我们可以使用:

#!/usr/bin/env

要么

#!/bin/env

Use first

which python

This will give the output as the location where my python interpreter (binary) is present.

This output could be any such as

/usr/bin/python

or

/bin/python

Now appropriately select the shebang line and use it.

To generalize we can use:

#!/usr/bin/env

or

#!/bin/env