我在 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
。