OSX:使用bash查找python与使用/usr/bin/env-python不同

OSX:使用bash查找python与使用/usr/bin/env-python不同,python,macos,bash,Python,Macos,Bash,我不知道该怎么看。如果我要求我的shell(bash)启动python,但没有给出确切的路径,那么它会以某种方式启动错误的程序(或者可能是正确的程序,但加载了错误的dylibs)。然而,whichpython和/usr/bin/env-python的输出看起来都很好 下面是我所说内容的一个示例: 好的,首先,我的python命令来自哪里?让我们跟随符号链接。(顺便说一句,太糟糕了,readlink-f和realpath在OSX上不存在…) $which python /usr/local/bin

我不知道该怎么看。如果我要求我的shell(bash)启动
python
,但没有给出确切的路径,那么它会以某种方式启动错误的程序(或者可能是正确的程序,但加载了错误的
dylib
s)。然而,
whichpython
/usr/bin/env-python
的输出看起来都很好

下面是我所说内容的一个示例:

好的,首先,我的
python
命令来自哪里?让我们跟随符号链接。(顺便说一句,太糟糕了,
readlink-f
realpath
在OSX上不存在…)

$which python
/usr/local/bin/python
$ls-l/usr/local/bin/python
lrwxr-xr-x 1根控制盘68 Jan 18 11:44/usr/local/bin/python@->../../../Library/Frameworks/python.framework/Versions/2.7/bin/python
$ls-l/Library/Frameworks/Python.framework/Versions/2.7/bin/Python
lrwxr-xr-x 1 root admin 7 Jan 18 11:44/Library/Frameworks/Python.framework/Versions/2.7/bin/Python@->python2
$ls-l/Library/Frameworks/Python.framework/Versions/2.7/bin/python2
lrwxr-xr-x 1 root admin 9 Jan 18 11:44/Library/Frameworks/Python.framework/Versions/2.7/bin/python2@->python2.7
$ls-l/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
-rwxr-x 1 root admin 25624 Dec 5 15:57/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7*
如果我调用
/usr/local/bin/python
,那么
python
本身认为它位于哪里?它是什么版本的

$/usr/local/bin/python-c“导入系统;打印系统可执行文件;打印系统版本信息”
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
系统版本信息(主版本=2,次版本=7,微版本=11,版本级别=final,序列号=0)
好的,看起来合法。与其键入
/usr/local/bin/python
,不如让
/usr/bin/env
为我定位
python

$/usr/bin/env python-c“导入系统;打印系统可执行文件;打印系统版本\u信息”
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
系统版本信息(主版本=2,次版本=7,微版本=11,版本级别=final,序列号=0)
同样的事情。到目前为止没有什么意外。好的,如果我只是键入
python
?这应该与
/usr/bin/env python
相同,对吗

$python-c“导入系统;打印系统可执行文件;打印系统版本信息”
/usr/local/bin/python
系统版本信息(主版本=2,次版本=7,微版本=10,版本级别=final,序列号=0)
等等,什么<代码>系统可执行文件指向符号链接,版本错误。发生什么事了

为什么键入
python
与键入
/usr/local/bin/python
有任何不同

顺便说一句:

  • 我仔细检查了我的bash别名,
    python
    不是其中之一。(
    alias | grep python

当您从
$PATH
运行程序时(就像
$python
),它的
argv[0]
被设置为只是它的名称(例如
python
),而不是完整路径。Python2.7版本的
sys.executable
if
argv[0]
在beggining上没有反斜杠(例如,当您像上一个示例那样运行它时)。它似乎并没有解析符号链接,只是打印第一个找到的路径

我们可以看到,在OSX上,它在
$PATH
中对自身使用
NSGetExecutablePath
。他们说,
NSGetExecutablePath

也就是说,路径可能是符号链接,而不是实际文件


当您从
$PATH
运行程序时(就像
$python
),它的
argv[0]
被设置为只是它的名称(例如
python
),而不是完整路径。Python2.7版本的
sys.executable
if
argv[0]
在beggining上没有反斜杠(例如,当您像上一个示例那样运行它时)。它似乎并没有解析符号链接,只是打印第一个找到的路径

我们可以看到,在OSX上,它在
$PATH
中对自身使用
NSGetExecutablePath
。他们说,
NSGetExecutablePath

也就是说,路径可能是符号链接,而不是实际文件


Bash在内存中保留一个缓存的查找表,您可以使用
散列
检查该表。如果将与以前在不同位置使用的程序同名的程序添加到
路径中,
bash
仍将记住旧位置
env
显然绕过了这个缓存;或者您可以使用
hash-rpython
删除它


还要注意的是,
哪个
是不可移植的,通常不是正确的使用工具<代码>类型
由POSIX指定,并内置于任何现代shell中。

Bash在内存中保留一个缓存的查找表,您可以使用
哈希
进行检查。如果将与以前在不同位置使用的程序同名的程序添加到
路径中,
bash
仍将记住旧位置
env
显然绕过了这个缓存;或者您可以使用
hash-rpython
删除它


还要注意的是,
哪个
是不可移植的,通常不是正确的使用工具<代码>类型
由POSIX指定,内置于任何现代shell中。

感谢您的关注。我认为你的思路是对的。正如tripleee的回答所指出的,我需要运行
hash-rpython
来重新配置shell到python的路径。(我刚刚安装了一个新版本。)我认为bash仍然在从旧位置启动python,但是python的
sys.argv[0]
中没有反映出这个位置。因此,
python
本身对
sys.executable
使用了一个伪值。显然,这破坏了一切。顺便说一句,感谢您指向python sou中的相关行