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

时间:2016-01-18 17:58:52

标签: python macos bash

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

以下是我所谈论的内容的例证:

好的,首先,我的python命令来自哪里?让我们按照符号链接。 (BTW,太糟糕readlink -frealpath在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/pythonpython本身认为它位于何处?它的版本是什么?

$ /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无关?

顺便说一句:

  • 我仔细检查了我的bash别名,/usr/local/bin/python不是其中之一。 (python

2 个答案:

答案 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。