Linux 使用sudo时如何保留环境变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8633461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to keep environment variables when using sudo
提问by Ahmed Aswani
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.
当我对 sudo 使用任何命令时,环境变量不存在。例如,在设置 HTTP_PROXY 后,该命令在wget
没有sudo
. 但是,如果我输入sudo wget
它说它不能绕过代理设置。
采纳答案by Ahmed Aswani
The trick is to add environment variables to sudoers
file via sudo visudo
command and add these lines:
诀窍是sudoers
通过sudo visudo
命令将环境变量添加到文件并添加以下行:
Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
taken from ArchLinux wiki.
取自ArchLinux 维基。
For Ubuntu 14, you need to specify in separate lines as it returns the errors for multi-variable lines:
对于 Ubuntu 14,您需要在单独的行中指定,因为它返回多变量行的错误:
Defaults env_keep += "http_proxy"
Defaults env_keep += "https_proxy"
Defaults env_keep += "HTTP_PROXY"
Defaults env_keep += "HTTPS_PROXY"
回答by Employed Russian
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
。其次,你需要man sudo
仔细阅读,并注意-E
标志。这有效:
$ 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.
回答by Stian S
You can also combine the two env_keep
statements in Ahmed Aswani's answer into a single statement like this:
您还可以将env_keep
艾哈迈德·阿斯瓦尼 (Ahmed Aswani) 的回答中的两个语句组合成一个语句,如下所示:
Defaults env_keep += "http_proxy https_proxy"
Defaults env_keep += "http_proxy https_proxy"
You should also consider specifying env_keep
for only a single command like this:
您还应该考虑env_keep
仅指定一个命令,如下所示:
Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"
Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"
回答by buckaroo1177125
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"
回答by Wolfgang Fahl
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.
如果您需要将环境变量保存在脚本中,您可以将您的命令放在像这样的 here 文档中。特别是如果你有很多变量来设置这样看起来整洁的东西。
# 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
回答by Bruno Bronosky
A simple wrapper function (or in-line for loop)
一个简单的包装函数(或内联 for 循环)
I came up with a unique solution because:
我想出了一个独特的解决方案,因为:
sudo -E "$@"
was leaking variables that was causing problems for my commandsudo VAR1="$VAR1" ... VAR42="$VAR42" "$@"
was long and ugly in my case
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
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
这是通过 bash 内置功能实现的printf
。将%q
产生一个shell引号的字符串。与bash 4.4 中的参数扩展不同,这适用于 bash 版本 < 4.0