使用sudo时如何保持环境变量

时间:2011-12-26 06:26:58

标签: linux environment-variables sudo

当我使用sudo的任何命令时,环境变量不存在。例如,在设置HTTP_PROXY之后,wget命令在没有sudo的情况下正常工作。但是,如果我输入sudo wget,则表示无法绕过代理设置。

6 个答案:

答案 0 :(得分:423)

首先你需要export HTTP_PROXY。其次,您需要仔细阅读man sudo,并注意-E标志。这有效:

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

以下是手册页中的引用:

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

答案 1 :(得分:283)

诀窍是通过sudoers命令将环境变量添加到sudo visudo文件并添加以下行:

Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"

取自ArchLinux wiki

对于Ubuntu 14,您需要在单独的行中指定,因为它返回多变量行的错误:

Defaults  env_keep += "http_proxy"
Defaults  env_keep += "https_proxy"
Defaults  env_keep += "HTTP_PROXY"
Defaults  env_keep += "HTTPS_PROXY"

答案 2 :(得分:48)

对于您希望一次性使用的单个变量,您可以将其作为命令的一部分。

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

答案 3 :(得分:21)

你也可以将Ahmed Aswani答案中的两个env_keep陈述合并为一个这样的陈述:

Defaults env_keep += "http_proxy https_proxy"

您还应该考虑仅为一个命令指定env_keep

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

答案 4 :(得分:0)

如果需要将环境变量保存在脚本中,可以将命令放在此处的此处文档中。尤其是如果您有很多变量来设置内容时,看起来会很整洁。

# 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

答案 5 :(得分:0)

一个简单的包装函数(或内联for循环)

我想出了一个独特的解决方案,因为:

  • sudo -E "$@"正在泄漏导致我的命令出现问题的变量
  • sudo VAR1="$VAR1" ... VAR42="$VAR42" "$@"在我的情况下漫长而丑陋

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

结果

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

如何?

这是通过内置printf的bash功能实现的。 %q产生一个用外壳引号引起来的字符串。与the parameter expansion in bash 4.4不同,它可以在<4.0的bash版本中使用