[linux] How to keep environment variables when using sudo

When I use any command with sudo the environment variables are not there. For example after setting HTTP_PROXY the command wget works fine without sudo. However if I type sudo wget it says it can't bypass the proxy setting.

This question is related to linux environment-variables sudo

The answer is


First you need to export HTTP_PROXY. Second, you need to read man sudo carefully, and pay attention to the -E flag. This works:

$ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY'

Here is the quote from the man page:

-E, --preserve-env
             Indicates to the security policy that the user wishes to preserve their
             existing environment variables.  The security policy may return an error
             if the user does not have permission to preserve the environment.

You can also combine the two env_keep statements in Ahmed Aswani's answer into a single statement like this:

Defaults env_keep += "http_proxy https_proxy"

You should also consider specifying env_keep for only a single command like this:

Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"


A simple wrapper function (or in-line for loop)

I came up with a unique solution because:

  • sudo -E "$@" was leaking variables that was causing problems for my command
  • sudo VAR1="$VAR1" ... VAR42="$VAR42" "$@" was long and ugly in my case

demo.sh

#!/bin/bash

function sudo_exports(){
    eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) "$@"
}

# create a test script to call as sudo
echo 'echo Forty-Two is $VAR42' > sudo_test.sh
chmod +x sudo_test.sh

export VAR42="The Answer to the Ultimate Question of Life, The Universe, and Everything."

export _EXPORTS="_EXPORTS VAR1 VAR2 VAR3 VAR4 VAR5 VAR6 VAR7 VAR8 VAR9 VAR10 VAR11 VAR12 VAR13 VAR14 VAR15 VAR16 VAR17 VAR18 VAR19 VAR20 VAR21 VAR22 VAR23 VAR24 VAR25 VAR26 VAR27 VAR28 VAR29 VAR30 VAR31 VAR32 VAR33 VAR34 VAR35 VAR36 VAR37 VAR38 VAR39 VAR40 VAR41 VAR42"

# clean function style
sudo_exports ./sudo_test.sh

# or just use the content of the function
eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) ./sudo_test.sh

Result

$ ./demo.sh
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.

How?

This is made possible by a feature of the bash builtin printf. The %q produces a shell quoted string. Unlike the parameter expansion in bash 4.4, this works in bash versions < 4.0


If you have the need to keep the environment variables in a script you can put your command in a here document like this. Especially if you have lots of variables to set things look tidy this way.

# prepare a script e.g. for running maven
runmaven=/tmp/runmaven$$
# create the script with a here document 
cat << EOF > $runmaven
#!/bin/bash
# run the maven clean with environment variables set
export ANT_HOME=/usr/share/ant
export MAKEFLAGS=-j4
mvn clean install
EOF
# make the script executable
chmod +x $runmaven
# run it
sudo $runmaven
# remove it or comment out to keep
rm $runmaven

For individual variables you want to make available on a one off basis you can make it part of the command.

sudo http_proxy=$http_proxy wget "http://stackoverflow.com"

Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to environment-variables

Using Environment Variables with Vue.js Adding an .env file to React Project Is there any way to set environment variables in Visual Studio Code? Test process.env with Jest How to set environment variables in PyCharm? ARG or ENV, which one to use in this case? how to set ASPNETCORE_ENVIRONMENT to be considered for publishing an asp.net core application? What is a good practice to check if an environmental variable exists or not? Passing bash variable to jq Tensorflow set CUDA_VISIBLE_DEVICES within jupyter

Examples related to sudo

Composer: file_put_contents(./composer.json): failed to open stream: Permission denied How to run SUDO command in WinSCP to transfer files from Windows to linux How to install Intellij IDEA on Ubuntu? pip install: Please check the permissions and owner of that directory How to use sudo inside a docker container? How to fix 'sudo: no tty present and no askpass program specified' error? npm install errors with Error: ENOENT, chmod npm throws error without sudo Is it acceptable and safe to run pip install under sudo? Command not found when using sudo