我不知道该怎么做。如果我要求我的shell(bash)启动python
而不给它一个确切的路径,它会以某种方式启动错误的程序(或者可能是正确的程序,但加载了错误的dylib
。然而,which python
和/usr/bin/env python
的输出看起来都很好。
以下是我所谈论的内容的例证:
好的,首先,我的python
命令来自哪里?让我们按照符号链接。 (BTW,太糟糕readlink -f
和realpath
在OSX上不存在......)
$ which python
/usr/local/bin/python
$ ls -l /usr/local/bin/python
lrwxr-xr-x 1 root wheel 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
-rwxrwxr-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 "import sys; print sys.executable; print sys.version_info"
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
sys.version_info(major=2, minor=7, micro=11, releaselevel='final', serial=0)
好的,看起来合法。如果我让/usr/local/bin/python
为我找到/usr/bin/env
,该怎么办?
python
同样的事情。到目前为止没有惊喜。好的,如果我只输入$ /usr/bin/env python -c "import sys; print sys.executable; print sys.version_info"
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
sys.version_info(major=2, minor=7, micro=11, releaselevel='final', serial=0)
怎么办?这应该与python
相同,对吧?
/usr/bin/env python
等等,什么? $ python -c "import sys; print sys.executable; print sys.version_info"
/usr/local/bin/python
sys.version_info(major=2, minor=7, micro=10, releaselevel='final', serial=0)
指向符号链接,版本错误。发生了什么事?
为什么键入sys.executable
与键入python
无关?
顺便说一句:
/usr/local/bin/python
不是其中之一。 (python
)答案 0 :(得分:2)
当您从$PATH
运行程序时(因此,与$ python
一样),然后将argv[0]
设置为它的名称(例如python
),而不是完整路径。和sys.executable
looks at $PATH
的python 2.7版本,如果argv[0]
在开始时没有反斜杠(例如,当你像上一个例子一样运行它时)。似乎它没有解析符号链接,只打印第一个找到的路径。
我们可以看到in python's code,在OS X上,它在NSGetExecutablePath
中使用$PATH
。在Apple's site,他们说NSGetExecutablePath
也就是说,路径可能是符号链接,而不是真实文件。
答案 1 :(得分:2)
Bash将缓存的查找表保存在内存中,您可以使用hash
进行检查。如果您使用与以前在其他位置使用的程序同名的PATH
添加程序,bash
仍会记住旧位置。 env
显然绕过了这个缓存;或者您可以使用hash -r python
删除它。
另请注意,which
不可移植,通常不是正确使用的工具; type
由POSIX指定,并且内置于任何现代shell。