How to keep environment variables when using sudo
当我对sudo使用任何命令时,环境变量都不存在。例如,在设置了http-proxy之后,命令wget在没有sudo的情况下工作正常。但是,如果我输入sudo wget,它会说它不能绕过代理设置。
- Superuser.com/questions/232231/…
- Related:Why are path variants different when we running by Sudo and Su?在大学
首先,你需要用export HTTP_PROXY。其次,你要仔细阅读man sudo,注意-E旗。这工作:
1 2
| $ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY' |
以下是手册中的引述:
1 2 3 4
| -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. |
- 太好了,唯一的问题是修改一些配置文件,例如pacman for arch,使-e通过
- 要允许wget使用-e(保留环境),需要在sudo规则上指定setenv标记,该规则允许运行wget——例如:all=(root)nopasswd:setenv:
- 如果变量是path或pythonpath,则"-e"不起作用。
- 也不适用于任何LC_*变量。所以,只需执行export LOL_FOO=$LC_FOO并使用LOL_FOO。
- 这不适用于将一个元素添加到.bashrc文件中的PATH的简单情况,例如,export PATH=myPath:$PATH。如果我键入sudo -E bash -c 'echo $PATH',那么PATH不包含mypath,可能是因为sudo在调用bash之前已经禁用了PATH的本地值。相反,我发现下面的答案stackoverflow.com/a/33183620/5459638有效,即sudo PATH=$PATH command。
- 添加上述评论。假设package在mypath下,那么sudo PATH=$PATH which package会找到正确的答案,而不像sudo which package那样。但是,sudo PATH=$PATH package没有超过sudo package(找不到文件)。另一方面,从与sudo bash一起调用的shell中发射一个普通的package,保留了扩展路径,并赋予packagesudo权利(两只鸽子加一块石头)。因此,响应实际上取决于您正在启动的命令
- (setter)用户可能没有保留环境变量的权限:-E, --preserve-env ... . The security policy may return an error if the user does not have permission to preserve the environment.。
- @Xavierstuvw这是一个"明显"的安全措施,默认情况下不允许使用路径,因为用户可能会无意中执行一些非标准命令,结果和根权限都不符合预期。
- 记住,您也可以在内联中设置环境变量:HTTP_PROXY=val sudo -E bash -c 'echo $HTTP_PROXY'。
诀窍是通过sudo visudo命令将环境变量添加到sudoers文件中,并添加这些行:
1
| Defaults env_keep +="ftp_proxy http_proxy https_proxy no_proxy" |
取自archlinux wiki。
对于Ubuntu 14,您需要在单独的行中指定,因为它返回多变量行的错误:
1 2 3 4
| Defaults env_keep +="http_proxy"
Defaults env_keep +="https_proxy"
Defaults env_keep +="HTTP_PROXY"
Defaults env_keep +="HTTPS_PROXY" |
- 这无疑是避免信息泄漏和安全漏洞的最佳选择。不过,sudo -E是一种确保即兴发挥效果的方法,一次就能达到同样的效果。
- 我遇到了一个问题,就是一个调用sudo(jhbuild)的进程,我不能告诉它将-e标志传递给sudo,所以这是我的解决方案。
- 注意,您不应该直接编辑etc/sudoers。相反,使用visudo命令,它的语法在覆盖sudoers文件之前检查您的编辑。这样,如果在编辑时出错,就不会把自己锁在外面。
- 考虑使用大写env vars。在我的例子中,使用http_代理和https_代理就成功了。
- 将默认值限制为命令或用户的语法如下:unix.stackexchange.com/a/13246/66983
- 根据我的经验,小写变体更好,因为它同时适用于wget和curl。
- 以这种方式编辑/附加新的环境变量是否立即生效?或者需要重新启动服务器?即使在使用sudo visudo将其添加到Defaults env_keep +="VARNAME"之后,我似乎也无法保留我的~/.bash_profile导出的var。
- (继续)没想到,我把它放得太早了,在江户十一〔29〕号之前,哈哈!很高兴我找到了那个!
对于要一次性提供的单个变量,可以将其作为命令的一部分。
1
| sudo http_proxy=$http_proxy wget"http://stackoverflow.com" |
- 我在添加到PATH的.bashrc文件中(使用export条款)的mypath下测试了这个答案。然后,与sudo which package不同,sudo PATH=$PATH which package找到了正确的答案。但是,sudo PATH=$PATH package没有超过sudo package(找不到文件)。另一方面,从与sudo bash一起调用的shell中启动一个普通的package,保留了扩展的路径,并赋予packagesudo权利(两只鸽子加一块石头)。因此,响应实际上取决于您正在启动的命令
- sudo的路径解析是另一个问题——如果有人在搜索这个问题时发现了这篇文章,我建议您查看unix.stackexchange.com/questions/83191/…
您还可以将艾哈迈德·阿斯瓦尼的答案中的两个env_keep语句组合成一个这样的语句:
Defaults env_keep +="http_proxy https_proxy"
您还应该考虑只为这样的单个命令指定env_keep:
Defaults!/bin/[your_command] env_keep +="http_proxy https_proxy"