• sudo执行脚本找不到环境变量和命令


    简介

    变量

    普通用户下,设置并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
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    原因 
    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
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    不过可以直接通过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
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意看第一行的选项 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
    • 1
    • 2
    • 3
    • 4

    因此,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.
    • 1
    • 2

    简单来说,就是加上-E选项后,用户可以在sudo执行时保留当前用户已存在的环境变量,不会被sudo重置,另外,如果用户对于指定的环境变量没有权限,则会报错。

    $ sudo -E bash test.sh # 加上-E参数后就可以获取到变量 aaa 
    2. 修改sudo配置文件 
    在内部测试机器中,安全性要求不高,总是需要加上-E参数来执行脚本,这个安全设定也不是很方便,可以通过visudo命令来修改配置为保留原有的环境变量,具体修改如下

        $sudo visudo 
        # Defaults env_reset                  # 注释掉原有配置 
        # Defaults env_keep=”…”               # 注释掉指定的变量保持
    • 1
    • 2
    • 3

    Defaults !env_reset # 修改为不重置环境 
    3. 手动添加变量 
    手动在脚本中设置所需的变量,这样看起来比较麻烦,或者在执行sudo脚本前先将所需要的变量写入到要执行的脚本开头.

    命令

    对于自己安装的软件在sudo提示找不到的命令(没加sudo可以找到),在这个后面添加命令所在的路径

    secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 
    • 1
    secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:自定义路径 
  • 相关阅读:
    面向对象之设计模式大全
    JDK各版本新增的主要特性
    迷宫最短路径-货郎担问题的解决思路
    详细介绍Java垃圾回收机制
    并发编程与任务建模
    淘宝npm镜像使用方法
    Metrics-Java版的指标度量工具
    Velocity基本语法
    Git之”make sure you have the correct access…”
    Mysql的转义字符
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/8559741.html
Copyright © 2020-2023  润新知