非常简单的问题:在 Linux 中,为什么 Python 需要该行
#!/usr/bin/python
Run Code Online (Sandbox Code Playgroud)
在 python 文件的开头,因为 Windows 没有?
它有什么作用?因为“Python 链接”的描述有点含糊......
Kyl*_*and 71
Python对 Linux 没有任何这样的特殊要求。它是Unix/Linux 上的程序加载器,它使用所谓的“shebang”行。这实际上是一个功能而不是限制,但我们稍后会谈到。“shebang”上的 Wiki 页面有更多详细信息,但我将尝试在此处提供概述以及与 Windows 的比较。
首先我们来看看Windows上的情况:
.
以 Python 文件开头,通常是.py
..py
应该使用新安装的应用程序Python(即 Python 解释器)打开文件。.exe
,并且.bat
文件作为 Windows 批处理脚本执行。.py
使用运行文件python.exe
,而是应该使用其他程序打开它们,例如文本编辑器notepad.exe
。
python <scriptname>.py
(或编写一个.bat
文件来为您执行此操作)。现在,如果Python 脚本的顶部有一个 shebang 行(#!/usr/bin/python
或#!/usr/bin/env python
)会发生什么?好吧,由于#
是 Python 中的注释行,Python 解释器会忽略它。这就是 Unix/Linux 世界中使用的大多数脚本语言都用于#
开始注释行的原因之一。
所以说Windows“不需要”这#!
条线有点误导;Windows 没有看到该#!
行,实际上依靠文件扩展名来告诉它要做什么。这有几个缺点:
.py
在末尾命名 Python 脚本,以便自动识别它们。.py
文件类型的默认启动行为,Windows 将不再使用 Python 自动运行这些脚本。请注意,这可能是无意中完成的。现在,让我们看看 Unix/Linux 如何启动脚本:
首先要注意的是,Unix/Linux 与 Windows 不同,不会尝试使用特定程序“打开”Python 脚本,至少在概念上是这样;操作系统知道脚本是可以执行的,因为它被称为“执行位”(这超出了本答案的范围)。因此,如果您不小心输入了#!/usr/bin/pthon
而不是#!/usr/bin/python
,您将收到一条包含以下文本的错误消息:
/usr/bin/pthon: bad interpreter: No such file or directory.
Run Code Online (Sandbox Code Playgroud)
“解释器”一词为我们提供了有关 shebang 行角色的线索(尽管从技术上讲,指定的程序可以不是解释器,例如cat
或文本编辑器)。当您尝试执行文件时,会发生以下情况:
#!
,则加载程序将 shebang 行的其余部分(不包括 shebang 本身)解释为启动解释器的命令,通过该解释器将文件内容作为脚本运行。这有几个优点:
注意,最后,在Unix / Linux并没有 需要的家当线,以运行Python脚本。回想一下,shebang 行实际上所做的就是允许程序加载器选择一个解释器。但就像在 Windows 中一样,这可以手动完成:
python <myscript>
Run Code Online (Sandbox Code Playgroud)
Tho*_*ard 42
您指示的行用于告诉计算机在直接运行文件/脚本时使用什么程序/解释器,以及在脚本运行时应传递给该程序的任何参数。但是,这不是Python的要求,如果您打算直接运行脚本(而不是通过以下语法将其传递给 Python),则这是 linux 内核/系统的要求。
如果您要执行python script.py
或类似操作,则不需要它。仅当您打算直接运行脚本/文件时才需要它,而无需提供要使用的解释器(例如python
)。
对于 Bash 脚本,它应该是这样的:
#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;
Run Code Online (Sandbox Code Playgroud)
这将向系统表明,当它运行时,它应该通过/bin/bash
它是系统上的一种 shell/shell 脚本语言来运行。
但是,对于 Python 代码,在这里,您将希望通过 Python 运行可执行文件,因此您告诉它您打算在其中运行什么解释器。
#!/usr/bin/python [optional Python arguments]
# Python code here
...
exit()
Run Code Online (Sandbox Code Playgroud)
这与 Bash 一样,表示/usr/bin/python
应该使用(这可能是 Python 2 或 Python 3,具体取决于您的个人系统配置)。
通过这种方式,您可以运行./filename.py
或./executable
或./scripttorun
直接。
如果开头没有该行,并且假设您已将文件/脚本设置为可执行文件,并且假设您正在使用 Python 脚本,那么python filename.py
如果您没有该#!/usr/bin/python
行,则必须运行或类似。(对于 Bash 脚本,您必须bash script.sh
为其他脚本/语言(例如 Perl、Ruby 等)执行或类似操作。)
上面的语法突出显示在每个部分中都是特定于语言的,尽管这并不重要。
hee*_*ayl 16
线路:
#!/usr/bin/python
Run Code Online (Sandbox Code Playgroud)
被称为“shebang”,它表示将用于解释文件中其余命令的解释器二进制文件的路径。它通常是脚本的第一行。
因此该行#!/usr/bin/python
表示文件的内容将由python
位于/usr/bin/python
.
请注意,shebang 行由内核解析,然后脚本最终将作为参数调用:
python script_name
Run Code Online (Sandbox Code Playgroud)
类似的情况#!/bin/bash
:
bash script_name
Run Code Online (Sandbox Code Playgroud)
从技术上讲,它不需要它。它需要一个指向脚本执行环境的路径。你未来的脚本最好包含 /usr/bin/env 然后指定 python。这意味着无论 python 安装在哪里,您的脚本都可以在 python 环境中运行。出于兼容性原因,您想这样做,您无法确定与您共享代码的下一个人将在 usr/bin/python 中安装 python,或者他们是否有权访问这些系统文件。
在你的脚本中看起来是这样的:
#!/usr/bin/env python
Run Code Online (Sandbox Code Playgroud)
我也看到了一些关于如何指定 python3 的担忧。这是如何做到的:
#!/usr/bin/env python3
Run Code Online (Sandbox Code Playgroud)
小智 5
在 Linux 中,Python 可能需要也可能不需要#!
(shebang) 行。这取决于 Python 代码的处理方式,以 Python 交互模式或在 Python 脚本中运行代码。
Python交互模式允许用户直接输入和运行Python代码,不需要shebang行。要运行交互模式,请打开终端并输入python
Python 2.X 或python3
Python 3.X。
$ 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.
>>>
Run Code Online (Sandbox Code Playgroud)
Python 脚本允许用户将 Python 代码编写并保存在纯文本文件中,然后再运行这些代码。这可能需要也可能不需要 shebang 线。但是,在 Linux 中使用 Python 脚本需要 shebang 行时,有两个已知原因。
在可执行脚本中运行 Python 代码,即定义代码应该如何运行以及使用什么解释器;
运行与 Python 特定版本相关的 Python 代码,即仅运行与 Python 2.X 或 Python 3.X 兼容的代码
下面是文件的列表和内容,我用来展示#!
需要或不需要 (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
Run Code Online (Sandbox Code Playgroud)
hello1.py
仅包含源代码。
import sys
sys.stdout.write("Hello from Python %s\n" % (sys.version,))
print("Hello, World!")
Run Code Online (Sandbox Code Playgroud)hello2.py
包含源代码和shebang行。
#!/usr/bin/env python
import sys
sys.stdout.write("Hello from Python %s\n" % (sys.version,))
print("Hello, World!")
Run Code Online (Sandbox Code Playgroud)hello2e.py
包含与hello2.py
可执行文件相同的内容。
hello3.py
包含与 相同hello2.py
,但它通过将第一行重命名为 来适应与 Python 3 一起运行#!/usr/bin/env python3
。
hello3e.py
包含与hello3.py
可执行文件相同的内容。
hello3m.py
包含与hello3.py
可执行文件相同的内容,除了Write Unicode BOM
在文本编辑器中使用选项保存,即鼠标垫。
除此之外,用户将看到两种运行 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!
Run Code Online (Sandbox Code Playgroud)
两个版本的 Python 都能够成功运行脚本。因此,在shebang行不经由运行Python脚本时,需要python
或python3
命令。
下面是使用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!
Run Code Online (Sandbox Code Playgroud)
前三个脚本失败了,因为这些脚本是不可执行的,无论是否有 shebang 行(有关支持证明,请参阅下面的附加示例)。最后两个脚本有 shebang 行并且是可执行的。
显然,如果没有 shebang 行,已经可以执行的脚本基本上是无用的。因此,在可执行脚本中运行 Python 代码时,需要 shebang 行并且脚本必须是可执行的。
在我准备和测试的示例中,hello3m.py
作为可执行脚本运行失败并返回错误。
$ ./hello3m.py
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory
Run Code Online (Sandbox Code Playgroud)
这是一个已知的限制,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,))'
Run Code Online (Sandbox Code Playgroud)
运行此脚本时,首先,鼠标光标将更改为加号,并且在外观上没有任何作用。在单击桌面或终端窗口之前,不会显示语法错误。然后,此脚本将sys
在与脚本相同的目录中创建一个文件。
$ file sys
sys: PostScript document text conforming DSC level 3.0, Level 1
Run Code Online (Sandbox Code Playgroud)
该sys
文件已被识别为 PostScript 文件,没有文件扩展名。该文件可以在文档查看器(即 Evince)中打开,该文件实际上包含我之前单击的窗口的屏幕截图。根据我的经验,文件可以大到几兆字节。
再次强调,当将 Python 脚本作为可执行脚本运行时,shebang 行是必需的,并且脚本必须是可执行的。否则,脚本将按上述方式运行。
术语“可执行”或“必须是可执行的”是指运行脚本的权限。这是通过chmod +x FILENAME
在终端中运行命令来完成的,或者通过在文件管理器中的“属性”窗口中选中“允许此文件作为程序运行”选项或类似内容来完成。
虽然其他现有答案几乎涵盖了所有内容,但该答案通过使用实际示例来解释问题采取了不同的方法。代码语法经过精心编写,因此示例既可以使用 Python 2 也可以使用 Python 3 运行。
Python 代码改编自在 Windows 上使用 Python和在 Unix 平台上使用 Python,并附加了无处不在的“Hello, World!”一行代码。程序。
所有代码和命令都已经过全面测试,可以在Xubuntu 14.04系统下运行,默认安装了Python 2.7和Python 3.4。