取消设置 PATH 变量,并使用 shebang 执行 python 程序

Unset PATH variable, and execute python program with shebang

这让我绊倒了很多。

以下是foo.py

#!/usr/bin/env python

import sys
print(sys.executable)

有人可以解释 运行 bash 中以下命令的以下结果吗?

~$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-slackware-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
~$ ./foo.py
/usr/bin/python
~$ unset PATH
~$ ./foo.py

~$ PATH=
~$ ./foo.py

03:03:35 ~$ export PATH=""
03:03:42 ~$ ./foo.py
/usr/bin/env: ‘python’: No such file or directory

所以 env 使用 'execvp'(参见 man execvp),它来自 GNU coreutils env.c 中的 glibc。

引自手册页:

The execlp(), execvp(), and execvpe() functions duplicate the actions of the shell in searching for an executable file if the specified filename does not contain a slash (/) character. The file is sought in the colon-separated list of directory pathnames specified in the PATH environment variable. If this variable isn't defined, the path list defaults to the current directory followed by the list of directories returned by confstr(_CS_PATH). (This confstr(3) call typically returns the value "/bin:/usr/bin".)

可以用 'ltrace' 来验证这一点:

$ ltrace -o env ls

execvp(0x ... etc.

Python 的 sys.executable 也依赖于 PATH 变量。 在 execvp 运行 且环境中没有 PATH 变量的情况下,哪个是“未设置”[不存在]:

sys.executable

A string giving the absolute path of the executable binary for the Python interpreter, on systems where this makes sense. If Python is unable to retrieve the real path to its executable, sys.executable will be an empty string or None.

参考文献: