两位用户 @Graeme 和 @twalberg
Python无法检索到此内容的事实表明它正在进行自己的路径搜索(…)
是正确的。我不愿意相信Python会做一些像使用PATH
这样简单(愚蠢?)的事情来定位自己,但这是真的。
sys
模块在Python/sysmodule.c
文件中实现。截止到2.7.6版本,在第1422行设置了sys.executable
:
(…) 看起来sys.executable
在当前路径中搜索,而不是解析argv[0]
(或者可能是因为这种情况下argv[0]
就是Python本身...)(…)
SET_SYS_FROM_STRING("executable",
PyString_FromString(Py_GetProgramFullPath()));
Py_GetProgramFullPath()
函数定义在文件Modules/getpath.c
中,从701行开始:
char *
Py_GetProgramFullPath(void)
{
if (!module_search_path)
calculate_path();
return progpath;
}
函数 calcuate_path()
定义在同一文件中,包含以下注释:
/* If there is no slash in the argv0 path, then we have to
* assume python is on the user's $PATH, since there's no
* other way to find a directory to start the search from. If
* $PATH isn't exported, you lose.
*/
正如在我的情况中可以看到的那样,当首个导出到
$PATH
的Python与正在运行的Python不同时,也会出现问题。
有关计算解释器可执行文件位置的详细过程,请参阅
getpath.c
文件的
顶部:
在进行任何搜索之前,会确定可执行文件的位置。如果argv [0]中有一个或多个斜杠,则直接使用它。否则,它必须是从shell的路径中调用的,因此我们在$PATH中搜索命名的可执行文件并使用它。如果在$PATH上找不到可执行文件(或没有$PATH环境变量),则使用原始argv [0]字符串。
接下来,检查可执行文件位置是否为符号链接。如果是,则追踪该链接(如果发现相对路径名,则正确解释)并使用链接目标的目录。
让我们进行一些测试以验证上述内容:
如果argv [0]中有一个或多个斜杠,则直接使用它。
[user@localhost ~]$ sudo /usr/local/bin/python what_python.py
/usr/local/bin/python
2.7.6 (default, Feb 27 2014, 17:05:07)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]
好的。
如果在$PATH中找不到可执行文件(或者没有$PATH环境变量),则使用原始的argv [0]字符串。
[user@localhost ~]$ sudo PATH= python what_python.py
<empty line>
2.7.6 (default, Feb 27 2014, 17:05:07)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]
错误。在这种情况下,来自sys模块文档的说明是正确的 - 如果Python无法检索到其可执行文件的真实路径,则sys.executable将为空字符串或None。
让我们看看是否将Python二进制文件的位置添加回PATH
(在sudo删除后)可以解决问题:
[user@localhost ~]$ sudo PATH=$PATH python what_python.py
/usr/local/bin/python
2.7.6 (default, Feb 27 2014, 17:05:07)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]
确实如此。
相关:
- Python问题 7774 - 如果修改了零命令参数,则sys.executable位置错误。
- Python问题 10835 - sys.executable默认和altinstall
- python-dev邮件列表线程 - 朝着更严格的sys.executable定义
- Stackoverflow 问题 - 如何在C中找到可执行文件的位置
ls -l /usr/bin/python
命令,看看以超级用户身份登录时是否指向了不同的可执行文件?虽然很奇怪,但这是有可能的。 - Corley Brigman[user@localhost ~]$ sudo ls -l /usr/bin/python
的输出结果是-rwxr-xr-x 2 root root 8304 Oct 23 2012 /usr/bin/python
。 - Piotr Dobrogostsys.executable
似乎在搜索当前路径时解析了argv[0]
(或者可能是因为在这种情况下argv[0]
只是python
...),而不一定是由sudo
启动的可执行文件,因为sudo
在调用python
之前改变了PATH,但它已经解析了要调用的python
。 - twalberg/proc/self/exe
下解析链接。如果python
没有这样做,而是在搜索PATH
,那么这就可以解释差异。您可以编写一个脚本来显示/proc/self/exe
的目标和sys.executable
,或者使用我下面的建议,在程序运行时外部检查。 - Graeme