sudo execution script could not find environment variables

brief introduction

Under the normal user, setting and export ing a variable, then executing echo command with sudo, can get the value of the variable. But if the echo command is written into the script, then sudo executes the script, the variable can not be found, and the value can not be obtained. The following is the case:

$ cat tesh.sh 
echo $var 
$ var=aaa 
$ export var                       # export variable 
$ sudo echo $var                   # sudo executes echo commands, returning variable values 
aaa 
$ sudo bash test.sh                # sudo executes scripts and cannot get variable values 

$ bash test.sh                     # Ordinary users execute scripts and return variable values 
aaa

Reason
When sudo runs, it defaults to reset the environment variable to a safe environment variable, that is, the previously set variables will fail, and only a few of the environment variables specified in the configuration file can be saved.

The sudo configuration file is / etc/sudoers that requires root privileges to read:

$ 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

However, you can view sudo's limitations directly through sudo-l:

$ 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

Note that the option Defaults env_reset in the first line means that the environment variables will be reset by default, so that the variables you define will fail in sudo and cannot be retrieved.
In addition, some distributions have an option of Defaults env_keep=""to keep part of the environment variables from being reset, and the variables that need to be reserved are written in double quotes.

Why can sudo echo $var get variable values?
Since sudo execution resets environment variables, why can echo get the corresponding variables?
This is due to the shell command line replacement-reorganization function. When entering the command and pressing Enter, the shell will first cut the command line into fields according to the separator, find out whether there are variables or command substitution for each field, and then reorganize it into new commands, and then execute it.
Therefore, the actual execution of the command is:

$ sudo echo $var                   # $var => aaa 
(sudo echo aaa)                    # Complete Command Replacement & Reorganization 
(echo aaa)                         # Execution in sudo environment 
aaa

Therefore, when the sudo environment is reset, instead of referring to the variable $var, it is echo aaa directly.

Solve

  1. sudo -E

    - The E option is explained in man page as follows:

-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.

Simply put, with the - E option, the user can retain the existing environment variables of the current user when sudo is executed without being reset by sudo. In addition, if the user does not have permission for the specified environment variables, it will report an error.

Suo-E bash test.sh # with the - E parameter obtains the variable aaa
2. Modify sudo configuration file
In the internal test machine, the security requirement is not high, always need to add - E parameter to execute the script, this security setting is not very convenient, you can modify the configuration to retain the original environment variables through the visudo command, the specific modifications are as follows

    $sudo visudo 
    # Defaults env_reset                  # Annotate the original configuration 
    # Defaults env_keep="..."               # Comment out the specified variable holder

Defaults! Env_reset# changed to no reset environment
3. Manual addition of variables
Setting the required variables manually in the script may seem cumbersome, or writing the required variables to the beginning of the script to be executed before executing the sudo script.

Keywords: sudo shell

Added by fredyap1234 on Thu, 04 Jul 2019 00:38:25 +0300