我在IPython REPL中调用pip时遇到了一些问题,过了一段时间后我注意到IPython没有使用与我的shell相同的$ PATH环境。
$ echo $PATH
/Users/jimmy/dev/anaconda/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/texbin
$ ipython
In [1]: !echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/texbin:/Users/jimmy/dev/anaconda/bin
它确实似乎扰乱了路径顺序,我不太清楚什么是错的。
我使用通过oh-my-zsh安装的ZSH作为shell,如果有帮助的话。
这是sys.path()
返回的内容:
['',
'/Users/jimmy/dev/anaconda/bin',
'/Users/jimmy/dev/anaconda/lib/python2.7/site-packages/sparsesvd-0.2.2-py2.7-macosx-10.5-x86_64.egg',
'/Users/jimmy/dev/projects/pyresult',
'/Users/jimmy/dev/work/gavagai/userdata',
'/Users/jimmy/dev/work/gavagai/gavapi',
'/Users/jimmy/dev/anaconda/python.app/Contents/lib/python27.zip',
'/Users/jimmy/dev/anaconda/python.app/Contents/lib/python2.7',
'/Users/jimmy/dev/anaconda/python.app/Contents/lib/python2.7/plat-darwin',
'/Users/jimmy/dev/anaconda/python.app/Contents/lib/python2.7/plat-mac',
'/Users/jimmy/dev/anaconda/python.app/Contents/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/jimmy/dev/anaconda/python.app/Contents/lib/python2.7/lib-tk',
'/Users/jimmy/dev/anaconda/python.app/Contents/lib/python2.7/lib-old',
'/Users/jimmy/dev/anaconda/python.app/Contents/lib/python2.7/lib-dynload',
'/Users/jimmy/dev/anaconda/lib/python2.7/site-packages/runipy-0.1.0-py2.7.egg',
'/Users/jimmy/dev/anaconda/lib/python2.7/site-packages/setuptools-3.6-py2.7.egg',
'/Users/jimmy/dev/anaconda/lib/python2.7/site-packages',
'/Users/jimmy/dev/anaconda/lib/python2.7/site-packages/PIL',
'/Users/jimmy/dev/anaconda/lib/python2.7/site-packages/IPython/extensions',
'/Users/jimmy/.ipython']
这就是os.environ['PATH']
返回的内容:
'/Users/jimmy/dev/anaconda/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/texbin'
两者似乎都按照正确的顺序排列。
感谢所有人的帮助。
答案 0 :(得分:8)
总结和补充@holdenweb's helpful answer,特别是关于OS X:
!
是非交互式 非登录用户默认的实例> shell - 即使IPython是从不同的 shell启动的。
path/to/default/shell -c ...
!ps -p $$ && :
echo $SHELL
始终告诉您默认 shell - 即使是从不同的 shell运行。
初始化文件:
zsh:
:/etc/zshenv
和~/.zshenv
bash
:$BASH_ENV
变量中指向的脚本(如果已定义)。 正如所指出的,shell会根据是否加载不同/附加的初始化文件:
请注意,登录shell可以是交互式的,也可以不是,而且交互式shell可以是登录shell。
因此,在本案例中,可能两个附加的初始化文件被加载到交互式 shell中,解释了交互式shell和创建的子shell之间的行为差异通过IPython:
~/.zprofile
- 如果shell是 login shell - 如果zsh
是默认 shell,则会出现这种情况(在OS X上) ,在Terminal.app
等终端中创建的默认shell的所有交互式实例都是登录shell。~/.zshrc
最后,在相关说明中,请注意在OS X上,NON-shell进程的默认$PATH
为:
/usr/bin:/bin:/usr/sbin:/sbin # Note the absence of /usr/local/bin.
且只有 shells 通过系统范围的初始化文件(调用/usr/local/bin
)将/usr/libexec/path_helper
(默认情况下为可扩展)添加到该文件中:
zsh
:
/etc/zshenv
zsh
实例生效。bash
(同样在sh
调用时),ksh
:
/etc/profile
结果是:
$PATH
(特别是没有/usr/local/bin
以及通过shell初始化文件添加的其他内容。)bash
/ sh
和ksh
非交互式非登录shell 不也只能看到默认的$PATH
。例如,当Alfred等GUI命令行启动程序创建shell实例时,会发生这种情况。zsh
未受影响,因为每个 /etc/zshenv
实例都会读取zsh
。 答案 1 :(得分:6)
首先,sys.path
与此无关;它只是Python解释器在导入模块时可以看到的位置列表,并不确定shell找到可执行程序的位置。但是,在该列表中可以看到PATH
的一些元素,因为解释器使用其可执行文件的路径在sys.path
上构建某些条目。
os.environ['PATH']
与运行IPython的环境中的$PATH
变量相同。 !echo $PATH
打印出IPython启动的子shell中的$PATH
变量,以执行shell转义(!
)。
一个可能的原因是IPython正在使用操作系统标准shell执行shell命令,该命令尚未定制为以zsh
具有相同的方式设置其路径。您可以通过执行IPython命令!echo $SHELL
来确认这一点。由于您确认不是这种情况,因此可以通过登录shell和交互式shell之间的差异来解释差异。
我不知道会告诉IPython使用另一个shell的配置项,但是可能有一个。作为一种解决方法,只需确保其他shell具有正确配置的路径,或者交互式shell也会看到您需要的环境。
请参阅@ mklement0对整个,血腥,凌乱细节的极其权威的答案。