How to keep environment variables when using sudo

前端 未结 6 740
滥情空心
滥情空心 2020-11-22 01:55

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

相关标签:
6条回答
  • 2020-11-22 02:27

    The trick is to add environment variables to sudoers file via sudo visudo command and add these lines:

    Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
    

    taken from ArchLinux wiki.

    For Ubuntu 14, you need to specify in separate lines as it returns the errors for multi-variable lines:

    Defaults  env_keep += "http_proxy"
    Defaults  env_keep += "https_proxy"
    Defaults  env_keep += "HTTP_PROXY"
    Defaults  env_keep += "HTTPS_PROXY"
    
    0 讨论(0)
  • 2020-11-22 02:31

    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"
    
    0 讨论(0)
  • 2020-11-22 02:33

    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

    0 讨论(0)
  • 2020-11-22 02:36

    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.
    
    0 讨论(0)
  • 2020-11-22 02:42

    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"

    0 讨论(0)
  • 2020-11-22 02:43

    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
    
    0 讨论(0)
提交回复
热议问题