当我使用sudo的任何命令时,环境变量都不存在。例如,在设置HTTP_PROXY之后,命令wget在没有sudo的情况下也能正常工作。但是,如果我输入sudo wget,它说它不能绕过代理设置。
HTTP_PROXY
wget
sudo
sudo wget
4szc88ey1#
首先,你需要export HTTP_PROXY。其次,你需要读取man sudo,并查看-E标志。这是有效的:
export HTTP_PROXY
man sudo
-E
$ export HTTP_PROXY=foof$ sudo -E bash -c 'echo $HTTP_PROXY'
$ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY'
字符串下面是来自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.
-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.
型
hk8txs482#
技巧是通过sudo visudo命令将环境变量添加到sudoers文件中,并添加以下行:
sudo visudo
sudoers
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"
Defaults env_keep += "http_proxy"
Defaults env_keep += "https_proxy"
Defaults env_keep += "HTTP_PROXY"
Defaults env_keep += "HTTPS_PROXY"
dnph8jn43#
对于希望一次性使用的单个变量,可以将其作为命令的一部分。
sudo http_proxy=$http_proxy wget "http://stackoverflow.com"
字符串
ztmd8pv54#
您也可以将Ahmed Aswani的回答中的两个env_keep语句合并合并为一个语句,如下所示:Defaults env_keep += "http_proxy https_proxy"个您还应该考虑仅为像这样的单个命令指定env_keep:Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"个
env_keep
Defaults env_keep += "http_proxy https_proxy"
Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"
nfeuvbwi5#
我提出了一个独特的解决方案,因为:
sudo -E "$@"
sudo VAR1="$VAR1" ... VAR42="$VAR42" "$@"
#!/bin/bashfunction sudo_exports(){ eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) "$@"}# create a test script to call as sudoecho 'echo Forty-Two is $VAR42' > sudo_test.shchmod +x sudo_test.shexport 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 stylesudo_exports ./sudo_test.sh# or just use the content of the functioneval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) ./sudo_test.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.shForty-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.
$ ./demo.sh
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.
这是通过bash内置的printf的一个特性实现的。%q生成一个shell引用的字符串。与the parameter expansion in bash 4.4不同,这在bash版本< 4.0时有效。
printf
%q
1sbrub3j6#
不知道是否所有的发行版都有这个功能,但在基于Debian的发行版中,在/etc/sudoers文件的尾部或附近有一行代码,其中包括文件夹/etc/sudoers.d。在这里,可以添加代码 “snippets” 来修改sudo的配置。具体来说,它们允许控制sudo中使用的所有环境变量。与/etc/sudoers一样,这些 “代码片段” 应该使用visudo进行编辑。您可以从阅读README文件开始,这也是一个方便的地方,可以保存您想要做的任何笔记:
/etc/sudoers
/etc/sudoers.d
visudo
README
$ sudo visudo -f /etc/sudoers.d/README # files for your snippets may be created/edited like so:$ sudo visudo -f /etc/sudoers.d/20_mysnippets
$ sudo visudo -f /etc/sudoers.d/README
# files for your snippets may be created/edited like so:
$ sudo visudo -f /etc/sudoers.d/20_mysnippets
关于sudo中环境配置的最详细的文档可能在man 5 sudoers的Command environment部分中找到。在这里,我们了解到默认情况下被阻止的 sudoers 环境变量可能会使用env_check或env_keep选项 “白名单”;例如:
man 5 sudoers
Command environment
env_check
Defaults env_keep += "http_proxy HTTP_PROXY"Defaults env_keep += "https_proxy HTTPS_PROXY"Defaults env_keep += "ftp_proxy FTP_PROXY"
Defaults env_keep += "http_proxy HTTP_PROXY"
Defaults env_keep += "https_proxy HTTPS_PROXY"
Defaults env_keep += "ftp_proxy FTP_PROXY"
型因此,在OP的情况下,我们可以像下面这样“传递”*sudoer的 * 环境变量:
$ sudo visudo -f /etc/sudoers.d/10_myenvwlist# opens the default editor for entry of the following lines: Defaults env_keep += "http_proxy HTTP_PROXY"Defaults env_keep += "https_proxy HTTPS_PROXY"# and any others deemed useful/necessary# Save the file, close the editor, and you are done!
$ sudo visudo -f /etc/sudoers.d/10_myenvwlist
# opens the default editor for entry of the following lines:
# and any others deemed useful/necessary
# Save the file, close the editor, and you are done!
OP可能是通过 * 反复试验 * 发现了sudo中缺少的环境变量。但是,也可以采取主动:在root提示符中可以获得所有环境变量及其允许或拒绝状态的列表(并且对于每个主机都是唯一的),如下所示:
root
# sudo -V...Environment variables to check for safety: ...Environment variables to remove: ...Environment variables to preserve:...
# sudo -V
...
Environment variables to check for safety:
Environment variables to remove:
Environment variables to preserve:
型注意,一旦一个环境变量被列入白名单,它将出现在sudo -V的后续清单中的“preserve”清单下。
sudo -V
zed5wv107#
如果你需要在脚本中保存环境变量,你可以把你的命令放在一个像这样的here文档中。特别是如果你有很多变量要设置的话,这样看起来更整洁。
# prepare a script e.g. for running mavenrunmaven=/tmp/runmaven$$# create the script with a here document cat << EOF > $runmaven#!/bin/bash# run the maven clean with environment variables setexport ANT_HOME=/usr/share/antexport MAKEFLAGS=-j4mvn clean installEOF# make the script executablechmod +x $runmaven# run itsudo $runmaven# remove it or comment out to keeprm $runmaven
# prepare a script e.g. for running maven
runmaven=/tmp/runmaven$$
# create the script with a here document
cat << EOF > $runmaven
# 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
7条答案
按热度按时间4szc88ey1#
首先,你需要
export HTTP_PROXY
。其次,你需要读取man sudo
,并查看-E
标志。这是有效的:字符串
下面是来自man page的引用:
型
hk8txs482#
技巧是通过
sudo visudo
命令将环境变量添加到sudoers
文件中,并添加以下行:字符串
来自ArchLinux wiki。
对于Ubuntu 14,您需要在单独的行中指定,因为它会返回多变量行的错误:
型
dnph8jn43#
对于希望一次性使用的单个变量,可以将其作为命令的一部分。
字符串
ztmd8pv54#
您也可以将Ahmed Aswani的回答中的两个
env_keep
语句合并合并为一个语句,如下所示:Defaults env_keep += "http_proxy https_proxy"
个您还应该考虑仅为像这样的单个命令指定
env_keep
:Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"
个nfeuvbwi5#
一个简单的 Package 函数(或内嵌for循环)
我提出了一个独特的解决方案,因为:
sudo -E "$@"
泄漏变量,导致我的命令出现问题sudo VAR1="$VAR1" ... VAR42="$VAR42" "$@"
在我的情况下又长又丑demo.sh
字符串
结果
型
怎么做?
这是通过bash内置的
printf
的一个特性实现的。%q
生成一个shell引用的字符串。与the parameter expansion in bash 4.4不同,这在bash版本< 4.0时有效。1sbrub3j6#
将代码段添加到/etc/sudoers.d
不知道是否所有的发行版都有这个功能,但在基于Debian的发行版中,在
/etc/sudoers
文件的尾部或附近有一行代码,其中包括文件夹/etc/sudoers.d
。在这里,可以添加代码 “snippets” 来修改sudo的配置。具体来说,它们允许控制sudo
中使用的所有环境变量。与
/etc/sudoers
一样,这些 “代码片段” 应该使用visudo
进行编辑。您可以从阅读README
文件开始,这也是一个方便的地方,可以保存您想要做的任何笔记:字符串
阅读'man 5 sudoers'的“命令环境”部分
关于
sudo
中环境配置的最详细的文档可能在man 5 sudoers
的Command environment
部分中找到。在这里,我们了解到默认情况下被阻止的 sudoers 环境变量可能会使用env_check
或env_keep
选项 “白名单”;例如:型
因此,在OP的情况下,我们可以像下面这样“传递”*sudoer的 * 环境变量:
型
从“# sudo -V”获取您的方位
OP可能是通过 * 反复试验 * 发现了
sudo
中缺少的环境变量。但是,也可以采取主动:在root
提示符中可以获得所有环境变量及其允许或拒绝状态的列表(并且对于每个主机都是唯一的),如下所示:型
注意,一旦一个环境变量被列入白名单,它将出现在
sudo -V
的后续清单中的“preserve”清单下。zed5wv107#
如果你需要在脚本中保存环境变量,你可以把你的命令放在一个像这样的here文档中。特别是如果你有很多变量要设置的话,这样看起来更整洁。
字符串