首先讲讲背景吧,我首先是遇到了一个问题,那就是在编译中我发现,当我使用sudo ./bash_create.sh(bash_create调用了cmake) 编译会报错。而当我使用su切换到root时,编译能通过不会报错。然后我便分别用root和普通用户测试了一下使用sudo和不使用sudo命令的情况,结果如下:
可以看到,无论是root还是ghs(普通用户)在使用cmake --version时显示的cmake版本都是3.0.0,而在使用sudo后都将显示2.8.12版本。这就奇怪了,因为一直以来,我都是将sudo命令当作短暂将普通用户提为root用户的一个命令,那么sudo后应该和root直接看version是一样的。
所以既然出现了这种情况,说明sudo可能并不仅仅是提升权限,还加了一些限制。
当然,在探索sudo的性质之前,要了解一些基础的知识。我们知道,在安装cmake/gcc之类的软件后,系统中便直接可以使用cmake/gcc的命令。为什么能达到这种效果呢?这是因为,这些软件在安装时一般被安装在/usr/bin这种目录下面,而如/usr/bin这种目录一般会被加入到root/用户的环境变量,所以在使用命令时系统会在环境变量中找到这个命令,并使用。我们所使用的系统命令如ls/pwd/reboot,实际上也是被加入了文件夹后然后将这个文件夹目录加入环境变量,这种之后便成为了我们日常所使用的“命令”。如此介绍之后,我们应该知道了环境变量的重要性,系统无论是使用全局命令或是软件都依赖于环境变量的添加。
在介绍了环境变量的重要性后,我们要知道的是不同用户的环境变量的配置是不同(这是很自然的,毕竟不同的用户安装了不同的软件,需要不同的全全局命令)。那么我们如何设置&查看环境变量呢?
首先,环境变量也有着不同的级别,有的环境变量是针对于系统的环境变量,而有的环境变量是针对于用户的,具体看:
/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。并从/etc/profile.d目录的配置文件中搜集shell的设置。
/etc/bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.
~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件.
~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该文件被读取.
~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件.
(另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是"父子"关系)
可以看到环境变量也是个复杂的系统。但实际使用中我们只需要查看一些简单而有效的环境变量便可以了,这时我们只需使用 echo $PATH 命令便可以显示当前环境的环境变量。
在了解了环境变量我们自然想查看不同用户的环境变量后,比如说root用户和普通的用户的环境变量,如下图:
看到好像两者是一样的,那么你就上当了,这就是第一个坑。
su & su -
一般来说,我们登陆的是普通用户,然后使用su命令切换成root用户。但是从普通用户切换成root用户的方式却是有两种的,
使用su不加任何参数,默认是切换到root用户,不变环境变量
使用su – 普通用户切换到root用户,改变环境变量
这种设计的目的就是为了能够更好的衔接用户使用的环境,因为一般来说用户即使切换到root后依然有可能使用在原来环境变量下使用的一些命令&软件,这样的设计令用户不会有一种切到root后好像有一些软件使用不了的情况出现。当然,如果一直使用su命令也会有问题,因为环境变量不变意味着你环境的配置或是软件的安装都是和普通用户一样,除了权限不同,那么在一些需要应用在全局(所有用户)的情况就会产生问题。
可以看到两个环境变量是不同的。
su&su -&sudo
在了解了一大堆前置知识后,我们终于可以开始解决使用sudo命令后显示不同的问题了。我们可以想到,这个问题应该是使用了sudo命令后环境变量不同的关系。那么,说明sudo命令所使用的环境变量既不是普通用户的环境变量又不是root用户的环境变量。
实际上,sudo命令使用时将PATH环境变量进行了重置,这实际上是一种安全性的考虑,目的显然是要限制用户运行 sudo 命令的范围,这是一种好做法。
我们可以使用 sudo visudo 命令(vi /etc/sudoers)修改文件。在secure_path可以看到sudo所设置的PATH环境变量:(这里有个冷知识:usr指的不是user而是Unix System Resource)
我们和前面普通用户&root的环境变量进行对比:
我们一个个目录找过来,发现在普通用户&root的环境变量中在/usr/local/bin最早出现cmake,而在sudo的环境变量中在/bin中最早出现cmake
在/usr/local/bin中cmake版本都是3.0.0
而在/bin中cmake版本是2.8.12
综上, su & su - & sudo命令所使用的环境变量的不同造成了这种问题。
对sudo想有进一步了解可以看:Developer