为什么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脚本,您需要手动调用
- 此信息记录在Windows注册表中; 安装Python时,它通常告诉Windows应该使用新安装的应用程序 Python(即Python解释器)打开
现在,如果在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/python
的python
二进制文件解释。
请注意,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行时有两个已知的原因。
-
在可执行脚本中运行Python代码,即定义代码应如何运行以及使用什么解释器;
-
针对特定版本的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都能够成功运行脚本。 因此,通过python
或python3
命令运行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
#!
部分通常被称为shebang或crunch爆炸 。
如果您安装了多个版本的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)。