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

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

#!/usr/bin/python 

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

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

Python对Linux没有任何这样的特殊要求。 这是Unix / Linux上的程序加载器 ,它使用了“shebang”行,就像它所说的那样。 这实际上是一个function而不是限制,但我们马上就会做到这一点。 关于“shebang”的Wiki页面有更多细节,但我会尝试在这里给出一个概述以及与Windows的比较。

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

  • 当您尝试打开或运行文件时,Windows首先检查该文件的扩展名 。 这是文件名的最后一部分. 对于Python文件,这通常是.py
  • Windows根据文件扩展名查找要执行的操作。
    • 此信息记录在Windows注册表中; 安装Python时,它通常告诉Windows应该使用新安装的应用程序 Python(即Python解释器)打开.py文件。
    • 一些文件类型具有内置行为; 例如,可执行文件(例如Python解释器本身)必须以.exe结尾,而.bat文件则作为Windows批处理脚本执行。
    • 对特定文件类型采取的操作是可自定义的 。 例如,您可以告诉Windows使用python.exe运行.py文件,而不是使用其他程序打开它们,例如文本编辑器notepad.exe
      • 在这种情况下,为了运行 Python脚本,您需要手动调用python .py (或编写.bat文件来为您执行此操作)。

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

所以说Windows“不需要” #!有点误导#! 线; Windows没有看到 #! line,实际上依赖于文件扩展名告诉它该怎么做。 这有几个缺点:

  • 必须在末尾使用.py命名Python脚本,以便自动识别它们。
  • 没有简单的方法可以区分Python2脚本和Python3脚本。
  • 如前所述,如果更改.py文件类型的默认启动行为,Windows将不再使用Python自动运行这些脚本。 请注意,这可能是无意中完成的。

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

首先要注意的是,与Windows不同,Unix / Linux不是试图使用特定程序“打开”Python脚本,至少在概念上是这样; 操作系统知道脚本是可以执行的,因为称为“执行位”(这超出了本答案的范围)。 因此,如果您不小心输入#!/usr/bin/pthon而不是#!/usr/bin/python ,您将收到包含此文本的错误消息:

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

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

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

这有几个好处:

  • 脚本编写者可以更好地控制将使用哪个解释器(这解决了Python2 / Python3问题),并且有时可以将额外的参数传递给解释器(有关详细信息,请参阅Wiki页面)。
  • 脚本的文件名被忽略 ,因此您可以根据需要命名Python脚本。

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

 python  

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

如果要执行python script.py或类似function,则不需要它。 只有在您打算直接运行脚本/文件时才需要它,而不需要提供使用的解释器(例如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脚本,那么你必须运行python filename.py或类似的,如果你没有#!/usr/bin/python line。 (对于Bash脚本,您必须执行bash script.sh ,或类似其他脚本/语言,如Perl,Ruby等)

上面的语法突出显示在每个部分中都是特定于语言的,尽管它并不重要。

这条线:

 #!/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,或者他们将拥有这些系统文件的权限。

这是堆栈溢出的类似问答 。

你的脚本中的样子是:

 #!/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包含与hello2e.py相同的并且是可执行文件。

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

  • hello3e.py包含与hello3e.py相同的hello3.py并使其成为可执行文件。

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

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

方法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,包括非可执行和可执行的案例。

 $ ./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! 

前三个脚本都失败了,因为这些脚本是不可执行的,无论是否有shebang行(有关支持certificate,请参阅下面的附加示例 )。 最后两个脚本有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,))' 

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

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

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

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

补充说明

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

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

Python代码改编自在Windows上 使用Python和在Unix平台上使用Python ,以及无处不在的“Hello,World!”的附加单行代码。 程序。

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

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

 ./[file-to-execute] 

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

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

#! 部分通常被称为shebangcrunch爆炸

如果您安装了多个版本的Python, /usr/bin/env将确保使用的解释器是您环境的$PATH的第一个。 另一种方法是硬编码#!/usr/bin/python ;

在Unix中,一个可以被解释的可执行文件可以通过#!来指示要使用的解释器#! 在第一行的开头,然后是解释器(以及它可能需要的任何标志)。

此规则仅适用于基于UNIX的系统。

有助于像Linux这样的操作系统,其中Python 2.x仍然是标准,但大多数人也下载3.x.

2.x默认运行。 所以我的3.x代码,我用#!/ usr / bin / env python3作为前缀,以便3.x运行代码。 如果我选择测试版或稍微旧版本,我甚至可以指定小修订版(python 3.xyz)。