![为什么“which”会给出错误的结果?](https://linux22.com/image/1370117/%E4%B8%BA%E4%BB%80%E4%B9%88%E2%80%9Cwhich%E2%80%9D%E4%BC%9A%E7%BB%99%E5%87%BA%E9%94%99%E8%AF%AF%E7%9A%84%E7%BB%93%E6%9E%9C%EF%BC%9F.png)
我在 Ubuntu 12.04 shell 上执行以下命令:
sudo bash -c "echo $PATH; which python"
显示类似
/home/me/env/develop/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
/usr/bin/python
以及以下命令
ls /home/me/env/develop/bin
显示(以及其他)
python
根据man
页面,该which
命令会在 中定义的所有路径中查找给定的可执行文件PATH
。该man
页面没有严格指定搜索的“顺序”,但通常从环境变量的开头到结尾PATH
。
现在,路径/home/me/env/develop/bin
包含一个python可执行文件(模式设置正确,而不是符号链接),这也是中的第一个路径PATH
。但which
命令显示的位置完全不同!
这是为什么?我是不是在做蠢事?这跟魔法有关吗sudo
?这是 bug 吗?
答案1
这不是一个错误。$PATH
双引号内的内容在 shellbash -c
看到它之前就被扩展了。
这意味着你实际上会运行:
sudo bash -c "echo /home/me/env/develop/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games; which python"
小测试:
$ foo="hello"
$ sudo bash -c "echo $foo"
hello
要找到问题的根源,请运行:
sudo bash -c 'echo $PATH; which python'
这以前不会扩大$PATH
。
解决路径问题的一个方法是将路径设置为.bashrc
而不是.bash_profile
— — 如果我没记错的话,您的路径设置在那里 — — 这样即使对于非登录 shell 也会加载它(如bash -c
)。或者您运行bash -lc
以让它运行登录 shell,这将加载.bash_profile
。