当我用sudo使用任何命令时,环境变量都不存在。例如,在设置HTTP_PROXY之后,wget命令没有sudo也可以正常工作。但是,如果我输入sudo wget,它说它不能绕过代理设置。
当前回答
诀窍是通过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"
其他回答
首先,您需要导出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.
诀窍是通过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"
对于您希望一次性可用的单个变量,您可以将其作为命令的一部分。
sudo http_proxy=$http_proxy wget "http://stackoverflow.com"
如果您需要将环境变量保存在脚本中,您可以将您的命令放在如下的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
一个简单的包装器函数(或内联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.
How?
这是由bash内置printf的一个特性实现的。%q产生一个带引号的shell字符串。与bash 4.4中的参数展开不同,这适用于bash < 4.0版本
推荐文章
- 如何从命令行在windows中找到mysql数据目录
- 如何在Makefile中设置子进程的环境变量
- 有效地测试Linux上的端口是否打开?
- 如何从另一个文件A中删除文件B中出现的行?
- 对以制表符分隔的文件进行排序
- 使用sudo时未找到命令
- 当有命令行参数时,如何使用GDB分析程序的核心转储文件?
- 如何强制从另一个SSH会话分离屏幕?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- Linux Bash中双&和分号有什么区别?
- 如何在POM.xml中引用环境变量?
- 在SSH会话中查找客户端的IP地址
- C++ Linux的想法?
- 如何为Fedora安装g++ ?
- 环境变量存储在Windows注册表的哪里?