Posted on 

bash common sense issues

今天遇到一个经验上的一个陷阱,蛮有意思的。
小伙伴问我为什么 sudo 前后的 pip 位置不一样?

1
2
3
4
5
6
7
8
[guohao@localhost ~]$ sudo type pip
pip is /bin/pip
[guohao@localhost ~]$ type pip
pip is /usr/bin/pip
[guohao@localhost ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/guohao/.local/bin:/home/guohao/bin
[guohao@localhost ~]$ sudo echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/guohao/.local/bin:/home/guohao/bin

经验之谈就是 sudo 使用了 root 的 PATH 环境变量,然后 echo 一下 path 变量完全一致。

case 1:

1
2
3
4
5
6
[guohao@localhost ~]$ sudo bash
[root@localhost guohao]# type pip
pip is /bin/pip
[root@localhost guohao]# exit
[guohao@localhost ~]$ type pip
pip is /usr/bin/pip

发现 case 1 与之前的显示结果一致,type 符合预期行为,从第一个 PATH 中打印 pip 的位置。这就很奇怪了,为什么切换到 shell 里面去和在外面的值不一致呢?

case2:

1
2
3
4
[guohao@localhost ~]$ echo 'echo $PATH' | sh
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/guohao/.local/bin:/home/guohao/bin
[guohao@localhost ~]$ echo 'echo $PATH' | sudo sh
/sbin:/bin:/usr/sbin:/usr/bin

诡异了只有 echo 不一样!难道是 sudo 的特别复杂的特性,然后 strace 一下发现是 bash 的导致我犯了一个思维定势的错误。

1
2
[guohao@localhost ~]$ strace sudo echo "$PATH"
execve("/usr/bin/sudo", ["sudo", "echo", "/usr/local/bin:/usr/bin:/usr/loc"...], 0x7ffcccc6e8f0 /* 17 vars */) = 0

顺便赞扬一下strace的便利与强大。