首页 > 代码库 > SUDO的环境变量为何不同?
SUDO的环境变量为何不同?
Refer: http://blog.sina.com.cn/s/blog_4da051a60102uyvg.html
当普通用户下,设置并export一个变量,然后利用sudo执行echo命令,能得到变量的值,但是如果把echo命令写入脚本,然后再sudo执行脚本,就找不到变量,未能获取到值,如题情况如下:
$ cat tesh.sh echo $var $ var=aaa $ export var # export 变量 $ sudo echo $var # sudo执行echo命令,返回变量值 aaa $ sudo bash test.sh # sudo执行脚本,不能获取变量值 $ bash test.sh # 普通用户执行脚本,返回变量值 aaa
原因
sudo运行时,会默认重置环境变量为安全的环境变量,也即,但前设置的变量都会失效,只有少数配置文件中指定的环境变量能保存下来。sudo的配置文件是 /etc/sudoers
需要root权限才能读取:
$ sudo sed ‘/^#/d;/^$/d’ /etc/sudoers Defaults env_reset Defaults mail_badpass Defaults secure_path=”/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin” root ALL=(ALL:ALL) ALL %sudo ALL=(ALL:ALL) ALL xxx ALL=(ALL:ALL) NOPASSWD:ALL
不过可以直接通过sudo -l
来查看sudo的限制:
$ sudo -l Matching Defaults entries for xxx on this host: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User xxx may run the following commands on this host: (ALL : ALL) NOPASSWD: ALL
意看第一行的选项Defaults env_reset
表示默认会将环境变量重置,这样你定义的变量在sudo环境就会失效,获取不到。
另外有的发行版还有一个Defaults
env_keep=""
的选项,用于保留部分环境变量不被重置,需要保留的变量就写入双引号中。
为什么sudo
echo $var
能获取到变量值?
既然利用sudo执行会重置环境变量,那么为什么还能echo获取到相应的变量呢?
这是由于shell命令行的替换&重组功能,在输入命令,按下回车时,shell会先依据分隔符将命令行切割成字段,对每个字段查找有没有变量或命令替换,再替换完成后,重组成新的命令,再去执行。
所以,命令实际执行是:
$ sudo echo $var # $var => aaa (sudo echo aaa) # 完成命令替换&重组 (echo aaa) # sudo环境中执行 aaa
因此,sudo环境重置后,并不用去引用$var
这个变量,而是直接echo aaa
。
解决
1、sudo -E
-E
选项在man page中的解释是:
-E
The -E (preserve environment) option indicates to the security policy that the user wishes to preserve their existing environment variables. The security policy may return an error if the -E option is specified and the user does not have permission to preserve the environment.
简单来说,就是加上-E
选项后,用户可以在sudo执行时保留当前用户已存在的环境变量,不会被sudo重置,另外,如果用户对于指定的环境变量没有权限,则会报错。
SUDO的环境变量为何不同?