Python - 如果未安装规定的版本,shebang 行应该做什么??如果 shebang 不是第一行怎么办?

Python - what is the shebang line supposed to do if the stated version is not installed ?? what if shebang is not the first line?

我必须更新遗留的 Python 2 程序,因此我想我会使用 shebang 行来确认在某些情况下使用的 Python 的正确版本。我以前没有使用过 shebang 系列,显然我不清楚它的目的和作用。

目前我使用的计算机安装了相对较新的 Ubuntu 18.04.5,Python 2 不是 尚未安装(Python 3 已安装)。我制作了一个名为 test.py 的测试脚本,内容如下:

#!/usr/bin/env python2
import sys
print(sys.version)

和运行它如下并收到以下结果:

$ python3 test.py 
3.6.9 (default, Oct  8 2020, 12:12:24) 
[GCC 8.4.0]

如你所见程序运行打印出来的版本,我看不懂。这真的是预期的行为吗?由于未安装 Python 2,因此我预计结果如下:

ERROR: Python 2 is not installed

我还有第二个问题,但在我提出这个问题之前我做了以下事情:

$ chmod +x test.py
$ ./test.py

并收到以下结果:

/usr/bin/env: ‘python2’: No such file or directory

根据脚本和这些命令,这将是我的预期结果,所以至少我对 shebang 行的信心部分恢复了,这让我想到了第二个问题。如果我修改 test.py 那么 shebang 不再是第一行,如下所示:

# test.py
#!/usr/bin/env python2
import sys
print(sys.version)

然后运行它:

$ ./test.py

终端挂起大约 30 秒,然后说:

import-im6.q16: not authorized `sys' @ error/constitute.c/WriteImage/1037.
./test.py: line 4: syntax error near unexpected token `sys.version'
./test.py: line 4: `print(sys.version)'

这与我完全删除 shebang 行得到的结果完全相同。这是预期的行为吗,即如果 shebang 行不是第一行但在其他方面是正确的,它应该什么都不做吗?

如果脚本是 运行,chmod +x test.py 然后是 ./test.py,shebang 就是 运行。然后 shell(即 bash)将 运行 /usr/bin/env python2 test.py。然而,当你明确地使用python3 test.py时,shell将不会检查你的shebang,它只会运行 python3.

此外,如果您将 shebang 放在第一行以外的任何行,它就不再是 shebang。引用 Wikipedia:

In computing, a shebang is the character sequence consisting of the characters number sign and exclamation mark (#!) at the beginning of a script.

shsebang只能在biginning。如果不是,那么 shell 将不会查看它,因此它 运行 test.py 作为 shell 脚本 ,其中许多找不到命令。

当您执行 python3 test.py 时,您已经告诉您的系统使用 python3 执行文件。 shebang 在这里毫无用处。 Shebang 适用于需要在文件中指定执行命令的情况。因此,如果您要添加一个 shebang,您假设那些使用您的代码的人将在将文件模式更改为可执行文件后使用 ./test 执行它。

因此 python3 test.py./test.py 之间的主要区别在于系统尝试 运行 脚本的方式。第一次尝试 python3 test.py 是 运行 直接通过已安装的 python 解释器编译脚本,并会执行任何有效的 python。如您所知,python 中的 # 表示后面的所有内容都是注释,应该被忽略,因此就解释器而言,第一个 shebang 并不“存在”。

现在 运行ning 脚本与 shell 有点不同。当 运行 直接使用脚本时,shebang 用于告诉您的系统 如何 运行 脚本/使用什么解释器。因此,当您尝试“./test.py”时,您的系统试图找到指定的解释器 python2 但找不到。因此,如果您的 shebang 是 #!/usr/bin/env bash,您的计算机将尝试 运行 您的脚本作为 bash 脚本,您可能会抛出很多语法错误。

shebang 对于 python 脚本来说不是必需的,但在许多情况下使用起来更简单,毕竟输入 ./script.shbash script.sh 更方便。最终用户不一定需要知道您的脚本如何 运行,只需要知道如何 运行 它。