当前位置: 首页>>技术问答>>正文


为什么Linux中的Python需要#!/usr/bin/python这一行?

, ,

问题描述

非常简单的问题:在Linux中,为什么Python需要该行

#!/usr/bin/python

在python文件的开头,因为Windows没有?

它有什么作用? ‘因为描述“链接到Python”有点模糊……

最佳解决方案

Python对Linux没有任何这样的特殊要求。它是Unix /Linux上的程序加载器,它使用”shebang”行,就像它所调用的那样。这实际上是一个功能而不是限制,但我们马上就会做到这一点。 The Wiki page on “shebang” has more details,但我会尝试在这里给出一个概述以及与Windows的比较。

首先,让我们看看Windows上的情况:

  • 当您尝试打开或运行文件时,Windows首先检查该文件的扩展名。这是以.开头的文件名的最后一部分。对于Python文件,这通常是.py

  • Windows根据文件扩展名查找要执行的操作。

    • 此信息记录在Windows注册表中;安装Python时,它通常告诉Windows应该使用newly-installed应用程序Python(即Python解释器)打开.py文件。

    • 几种file-types具有内置行为;例如,可执行文件(例如Python解释器本身)必须以.exe结尾,而.bat文件则作为Windows batch-scripts执行。

    • 对特定file-type采取的措施是可定制的。例如,您可以告诉Windows使用python.exe而不是运行.py文件,它应该使用其他程序打开它们,例如文本编辑器notepad.exe

      • 在这种情况下,为了运行Python脚本,您需要手动调用python <scriptname>.py(或编写.bat文件来为您执行此操作)。

现在,如果在Python脚本的顶部有一个shebang行(#!/usr/bin/python#!/usr/bin/env python)会发生什么?好吧,既然#是Python中的注释行,那么Python解释器就会忽略它。这就是Unix /Linux世界中使用的大多数脚本语言使用#来启动注释行的原因之一。

所以说Windows“不需要”#!线有点误导; Windows没有看到#!行,实际上依赖于file-extension来告诉它该怎么做。这有几个缺点:

  • 您必须在最后使用.py命名Python脚本,以便自动识别它们。

  • 没有简单的方法可以区分Python2脚本和Python3脚本。

  • 如前所述,如果更改.py file-type的默认启动行为,Windows将不再使用Python自动运行这些脚本。请注意,这可能是无意中完成的。

现在,我们来看看Unix /Linux如何启动脚本:

首先要注意的是,与Windows不同,Unix /Linux并没有尝试使用特定程序来编写”open” Python脚本,至少在概念上是这样;操作系统知道脚本是可以执行的,因为有一些叫做”execute bit”的东西(超出了这个答案的范围)。因此,如果您不小心键入#!/usr/bin/pthon而不是#!/usr/bin/python,您将收到包含此文本的错误消息:

/usr/bin/pthon: bad interpreter: No such file or directory.

单词”interpreter”为我们提供了关于shebang行的作用的线索(虽然从技术上讲,指定的程序可以是解释器之外的其他东西,例如cat或文本编辑器)。当您尝试执行文件时,会发生以下情况:

  • Unix /Linux程序加载器查看该文件的前两个字节;如果这两个字节是#!,则加载器将shebang行的其余部分(不包括shebang本身)解释为启动解释器的命令,使用该解释器将文件内容作为脚本运行。

  • 程序加载器启动指定的解释器,将其作为参数提供给原始文件的路径。

这有几个好处:

  • script-writer可以更好地控制将使用哪个解释器(这解决了Python2 /Python3问题),并且有时可以向解释器传递额外的参数(有关详细信息,请参阅Wiki页面)。

  • 脚本的文件名被忽略,因此您可以根据需要命名Python脚本。

最后,请注意,为了运行Python脚本,Unix /Linux不需要shebang行。回想一下,所有shebang行实际上都允许程序加载器选择一个解释器。但就像在Windows中一样,这可以手动完成:

python <myscript>

次佳解决方案

您指示的行用于告诉计算机直接运行文件/脚本时要使用的程序/解释器,以及脚本运行时应传递给该程序的任何参数。但是,这不是Python的要求,如果您打算直接运行脚本(而不是通过以下语法将其传递给Python),则需要Linux内核/系统。

如果要执行python script.py或类似操作,则不需要它。只有在您打算直接运行脚本/文件时才需要它,而不需要提供解释器(例如python)。


对于Bash脚本,它会有这样的东西:

#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;

这将向系统指示,当它运行时,它应该通过/bin/bash运行,这是系统上的shell /shell-script语言之一。


但是对于Python代码,在这里,您将希望通过Python运行可执行文件,因此您可以告诉它您打算在其中运行哪些解释器。

#!/usr/bin/python [optional Python arguments]
# Python code here
...
exit()

这与Bash一样,表示应该使用/usr/bin/python(这可能是Python 2或Python 3,具体取决于您的各个系统配置)。


这样,您可以直接运行./filename.py./executable./scripttorun

在开头没有该行,并假设您已将文件/脚本设置为可执行,并假设您正在使用Python脚本,如果您没有#!/usr/bin/python行,则必须运行python filename.py或类似行。 (对于Bash脚本,您必须执行bash script.sh,或类似其他脚本/语言,如Perl,Ruby等)

上面的语法突出显示是每个部分中的language-specific,尽管它并不重要。

第三种解决方案

这条线:

#!/usr/bin/python

称为’shebang’,它指示解释器二进制文件的路径,该路径将用于解释文件中的其余命令。它通常是脚本的第一行。

因此,行#!/usr/bin/python表示文件的内容将由位于/usr/bin/pythonpython二进制文件解释。

请注意,shebang行由内核解析,然后脚本最终将作为参数调用:

python script_name

同样在#!/bin/bash的情况下:

bash script_name

第四种方案

从技术上讲,它不需要它。它需要一个指向脚本执行环境的路径。你的未来脚本最好包含/usr /bin /env然后指定python。无论python安装在何处,您都可以在python环境中运行脚本。出于兼容性原因,您希望这样做,您不能确定与您共享代码的下一个人将在usr /bin /python中安装python,或者他们将拥有这些系统文件的权限。

Here is a similar Q&A from stack overflow

你的脚本中的样子是:

#!/usr/bin/env python

我也看到了如何指定python3的一些问题。这是怎么做的:

#!/usr/bin/env python3

第五种方案

在Linux中,Python可能需要也可能不需要#!(shebang)行。这取决于如何处理Python代码,无论是在Python交互模式下运行代码还是在Python脚本中运行代码。

Python交互模式允许用户直接键入和运行Python代码,这不需要shebang行。要运行交互模式,请打开终端并为Python 2.X键入python或为Python 3.X键入python3

$  python
Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

$  python3
Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Python脚本允许用户在纯文本文件中编写和保存Python代码,然后再运行代码。这可能需要也可能不需要shebang线。但是,在Linux中使用Python脚本需要shebang行时有两个已知的原因。

  1. 在可执行脚本中运行Python代码,即定义代码应该如何运行以及使用什么解释器;

  2. 根据特定版本的Python运行Python代码,即仅运行与Python 2.X或Python 3.X兼容的代码

用Python脚本练习

下面是文件的列表和内容,我用它来显示需要或不需要#!(shebang)行的情况。

$  ls -ln *.py
-rw-rw-r-- 1 1000 1000  94 Dec 14 18:37 hello1.py
-rwxrwxr-x 1 1000 1000 116 Dec 14 18:37 hello2e.py
-rw-rw-r-- 1 1000 1000 116 Dec 14 18:37 hello2.py
-rwxrwxr-x 1 1000 1000 117 Dec 14 18:37 hello3e.py
-rwxrwxr-x 1 1000 1000 120 Dec 14 18:37 hello3m.py
-rw-rw-r-- 1 1000 1000 117 Dec 14 18:37 hello3.py

$  file *.py
hello1.py:  ASCII text
hello2e.py: Python script, ASCII text executable
hello2.py:  Python script, ASCII text executable
hello3e.py: Python script, ASCII text executable
hello3m.py: Python script, UTF-8 Unicode (with BOM) text executable
hello3.py:  Python script, ASCII text executable
  • hello1.py仅包含源代码。

    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2.py包含源代码和shebang行。

    #!/usr/bin/env python
    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2e.py包含与hello2.py相同的并且可执行。

  • hello3.py包含与hello2.py相同的内容,但它适用于通过将第一行重命名为#!/usr/bin/env python3来运行Python 3。

  • hello3e.py包含与hello3.py相同的并且可执行。

  • hello3m.py包含与hello3.py相同并且可执行,除了在文本编辑器(即Mousepad)中使用Write Unicode BOM选项保存。

除此之外,还将向用户提供两种运行Python脚本的方法。两种方法都已经证明如下。

方法1:使用Python程序运行

下面是使用Python 2和Python 3运行源代​​码时的命令和输出。

$  python hello1.py
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  python3 hello1.py
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

两个版本的Python都能够成功运行脚本。因此,通过pythonpython3命令运行Python脚本时,不需要shebang行。

方法2:以Python脚本运行

下面是使用shebang行运行源代码时的命令和输出,它们既不适用于Python 2,也适用于Python 3,包括non-executable和可执行案例。

$  ./hello1.py
bash: ./hello1.py: Permission denied

$  ./hello2.py
bash: ./hello2.py: Permission denied

$  ./hello3.py
bash: ./hello3.py: Permission denied

$  ./hello2e.py 
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  ./hello3e.py 
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

前三个脚本失败,因为这些脚本是non-executable,无论是否有shebang行(有关支持证明,请参阅下面的附加示例)。最后两个脚本有shebang行并且是可执行的。

显然,如果没有shebang系列,已经可执行的脚本基本上是无用的。因此,shebang行是必需的,并且在可执行脚本中运行Python代码时脚本必须是可执行的。

当shebang不起作用

在我准备和测试的示例中,将hello3m.py作为可执行脚本运行失败并返回错误。

$  ./hello3m.py 
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory

这是一个已知的限制,即shebang不起作用或变得无效。当文件保存为Unicode BOM(字节顺序标记)时,它将无法作为可执行的Python脚本正常运行。

附加示例

此附加示例仅应视为支持证据。用户应该避免运行此示例,尽管结果是无害的。

我创建了另一个名为hello1e.py的文件,其中包含与hello1.py相同的文件并使其成为可执行文件。运行此脚本会返回语法错误。

$  ./hello1e.py 
./hello1e.py: line 2: syntax error near unexpected token `"Hello from Python %s\n"'
./hello1e.py: line 2: `sys.stdout.write("Hello from Python %s\n" % (sys.version,))'

运行此脚本时,首先,鼠标光标将更改为plus-sign并且在外观上不执行任何操作。在我点击桌面或终端窗口之前,不会显示语法错误。然后,此脚本将在与脚本相同的目录中创建sys文件。

$  file sys
sys: PostScript document text conforming DSC level 3.0, Level 1

sys文件已被标识为PostScript文件,没有文件扩展名。此文件可以在文档查看器中打开,即Evince,文件实际上包含我之前单击过的窗口的屏幕截图。根据我的经验,该文件可以大到几兆字节。

再次,shebang行是必需的,并且在将Python脚本作为可执行脚本运行时,脚本必须是可执行的。否则,脚本将如上所述行为不当。

补充说明

术语”made executable”或“必须可执行”是指运行脚本的权限。这可以通过在终端中运行chmod +x FILENAME命令,或通过在文件管理器中选中“允许此文件作为程序运行”或“属性”窗口中的类似内容来完成。

虽然其他现有答案几乎涵盖了所有内容,但这个答案采用了不同的方法,通过使用实际例子来解释这个问题。代码语法已经小心编写,因此示例可以使用Python 2或Python 3运行。

Python代码改编自Using Python on WindowsUsing Python on Unix platforms,以及无处不在的“Hello,World!”的附加one-line代码。程序。

所有代码和命令都经过了全面测试,可以在Xubuntu 14.04系统中运行,默认安装了Python 2.7和Python 3.4。

第六种方案

这意味着当执行该文件时,您的计算机知道使用程序/usr/bin/python执行它,这就是您如何区别于另一种语言,例如bash,您将执行#!/bin/bash。这样你就可以简单地运行:

./[file-to-execute]

并且它将知道要执行它的文件,而不是你自己必须指定类似的东西:

python ./[file-to-execute].py

#!部分通常被称为shebang或crunch bang。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/1543.html,未经允许,请勿转载。