一个很简单的问题:在Linux中,为什么Python需要该行
#!/usr/bin/python
在python文件的开头,因为Windows没有?
它有什么作用?因为描述“链接到Python”有点含糊...
python myscript.py
。
一个很简单的问题:在Linux中,为什么Python需要该行
#!/usr/bin/python
在python文件的开头,因为Windows没有?
它有什么作用?因为描述“链接到Python”有点含糊...
python myscript.py
。
Answers:
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如何启动脚本:
首先要注意的是,与Windows不同,Unix / Linux至少在概念上没有尝试使用特定程序“打开” Python脚本。OS 知道脚本是可以执行的,因为有一个称为“执行位”的东西(不在此答案的范围之内)。因此,如果您不小心输入#!/usr/bin/pthon
而不是#!/usr/bin/python
,则会收到一条包含以下文本的错误消息:
/usr/bin/pthon: bad interpreter: No such file or directory.
“解释器”一词为我们提供了有关shebang行的作用的线索(尽管从技术上讲,指定程序可以是解释器(例如cat
或文本编辑器)以外的其他东西。当您尝试执行文件时,会发生以下情况:
#!
,则加载程序将shebang行的其余部分(shebang本身除外)解释为命令,以启动解释器,使用该解释器将文件内容作为脚本运行。这有两个优点:
请注意,最后,在Unix / Linux并没有 需要的家当线,以运行Python脚本。回想一下,shebang行实际上所做的只是允许程序加载器选择解释器。但是就像在Windows中一样,这可以手动完成:
python <myscript>
.py2
和.py3
扩展Python 2 / Python 3脚本。因此,Linux(+ x位)和Windows(文件扩展名)都需要文件系统中的元数据。主要区别在于+ x位在传输中更容易丢失。这不一定是不利的。
/usr/bin/i686/python
,该/usr/bin/amd64/python
怎么办?完全合理,但是它破坏了对进行硬编码假设的python脚本/usr/bin/python
。解释器的选择不是脚本编写者的选择,而是脚本用户的选择,脚本编写者只能选择语言(方言)。
/usr/bin/env
它的用途,以及env-setup脚本。Windows的版本是什么?regedit
在启动.py
文件之前立即运行脚本,以确保获得所需的解释器?
您所指示的行用于告诉计算机直接运行文件/脚本时使用什么程序/解释器,以及在脚本运行时应传递给该程序的所有参数。但是,这不是Python的要求,如果您打算直接运行脚本(而不是通过以下语法将其传递给Python),则这是Linux内核/系统的要求。
如果要执行python script.py
或类似操作,则不需要它。仅当您打算直接运行脚本/文件而不提供解释器(例如python
)时才需要它。
对于Bash脚本,它将具有以下内容:
#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;
这将向系统指示,当它运行时,应该通过/bin/bash
它运行系统上的shell / shell脚本语言之一。
但是,对于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
行,则必须运行或进行类似操作。(对于Bash脚本,您必须这样做bash script.sh
,或对其他脚本/语言(例如Perl,Ruby等)执行类似操作。)
上面的语法高亮在每个部分中都是特定于语言的,尽管并不重要。
#!/bin/bash -x
,#!/usr/bin/perl -lan
,等)。
/usr/bin/env python
来获取正确的python 时,它就是PITA 。
env
,但问题似乎不在于参数的数量:#!/usr/bin/perl -l -a -n
具有三个参数,但是可以使用。再次说明,我无法解决确切的问题。
./
。换句话说,公正python filename.py
或bash script.sh
将工作正常。要包含./
在命令行中的唯一原因是要告诉外壳程序不要搜索$PATH
(它可能不会在当前目录中找到文件)而是采用原样指定的路径。但这不适用于命令参数。
env
从内核接收其余的参数。可以将它们全部假定为一个大参数,而不执行按空间分割。很抱歉表达清楚,我现在不记得这个细节了
该行:
#!/usr/bin/python
称为“ shebang”,它表示解释器二进制文件的路径,该文件将用于解释文件中的其余命令。它通常是脚本的第一行。
因此,该行#!/usr/bin/python
表明文件的内容将由python
位于的二进制文件解释/usr/bin/python
。
请注意,shebang行由内核解析,然后该脚本最终将被作为参数调用:
python script_name
在以下情况下类似#!/bin/bash
:
bash script_name
shebang
。由于该单词是由“哈希”和“爆炸”构成的,因此您的拼写不是很清楚,因为它看起来像是“她”和“爆炸”的组合。
hashbang
(#
=“ hash”)或shebang
(#
=“ sharp”),具体取决于您如何命名#
角色。但是,shebang
确实更普遍。@KyleStrand
从技术上讲,它不是必需的。它需要一个脚本执行环境的路径。您将来的脚本最好包含/ 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
Python 2.X或python3
Python3.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.
>>>
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
包含hello2.py
和并使其可执行。
hello3.py
包含与相同的内容hello2.py
,不同之处在于它通过将第一行重命名为来与Python 3配合使用#!/usr/bin/env python3
。
hello3e.py
包含hello3.py
和并使其可执行。
hello3m.py
包含hello3.py
与之相同的文件并使其可执行,除了Write Unicode BOM
在文本编辑器(即Mousepad)中与选项一起保存外。
除此之外,还将为用户提供两种方法来运行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都能成功运行脚本。因此,在shebang行不经由运行Python脚本时,需要python
或python3
命令。
方法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行(有关支持的证明,请参见下面的其他示例)。最后两个脚本具有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,与无处不在的额外一行代码“你好,世界!” 程序。
所有代码和命令都经过了全面测试,并且可以在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”。
.
)来确定文件的类型。甚至Windows都在远离它:检查Microsoft Word文件的前几行,它会声明它实际上是Microsoft Word文件。