Pio*_*ost 9 python linux sudo env
安装了两个Python解释器:
[user@localhost ~]$ /usr/bin/python -V && /usr/local/bin/python -V
Python 2.4.3
Python 2.7.6
Run Code Online (Sandbox Code Playgroud)
PATH它运行的每个命令的Sudo更改如下:
[user@localhost ~]$ env | grep PATH && sudo env | grep PATH
PATH=/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/user/bin
PATH=/usr/bin:/bin
Run Code Online (Sandbox Code Playgroud)
我运行一个测试脚本:
[user@localhost ~]$ cat what_python.py
#!/usr/bin/env python
import sys
print sys.executable
print sys.version
[user@localhost ~]$ sudo python what_python.py
/usr/bin/python
2.7.6 (default, Feb 27 2014, 17:05:07)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]
Run Code Online (Sandbox Code Playgroud)
并获取Python 2.4.3 in sys.executable和2.7.6版中的路径sys.version.显然sys.executable,sys.version不匹配.考虑到sudo如何修改PATH,我可以理解它的价值sys.executable.但是,为什么sys.version报告版本2.7.6而不是版本2.4.3,它会匹配usr/bin/python报告的路径sys.executable?
这是我的问题的后续事件Sudo更改PATH,但执行相同的二进制文件
两个都是@Graeme
python可能无法检索到这一事实表明它正在进行自己的PATH搜索(...)
和@twalberg
(...)看起来sys.executable搜索当前的PATH而不是解析argv [0](或者因为argv [0]在这种情况下是简单的python ...),(...)
基本上是对的.我不愿意相信Python做的事情如此简单(愚蠢?)就像PATH用来定位自己一样,但事实确实如此.
Python的sys模块在Python/sysmodule.c文件中实现.从版本2.7.6开始,sys.executable在第1422行设置如下:
SET_SYS_FROM_STRING("executable",
PyString_FromString(Py_GetProgramFullPath()));
Run Code Online (Sandbox Code Playgroud)
Py_GetProgramFullPath()函数在文件中定义,Modules/getpath.c从第701行开始:
char *
Py_GetProgramFullPath(void)
{
if (!module_search_path)
calculate_path();
return progpath;
}
Run Code Online (Sandbox Code Playgroud)
函数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.
*/
Run Code Online (Sandbox Code Playgroud)
从我的情况可以看出,当导出的第一个Python $PATH与正在运行的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)]
Run Code Online (Sandbox Code Playgroud)
好.
如果在$ 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)]
Run Code Online (Sandbox Code Playgroud)
错误.在这种情况下,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)]
Run Code Online (Sandbox Code Playgroud)
确实如此.
有关: