请考虑以下代码段:
$ export xx=foo
$ sudo bash -c 'echo $xx ~'
/root
没关系。我们看不到xx。
但是,如果我公开它:
$ sudo -E bash -c 'echo $xx ~'
foo /home/xropi
虽然很多人说~不是别名,但不知何故它是环境的一部分,因为-E会暴露原件,阻止我推迟评估。
是否可以在 sudo-ed 命令中传递我的变量并评估 ~ 作为 /root ?
我想在使用 sudo 运行时得到这个:
foo /root
您对波浪号如何工作的理解是不完整的。查看
man bash
并搜索Tilde Expansion
。它以(我添加的额外换行符和一些粗体)开头:
简而言之,
~
如果 $HOME 不为空,则扩展为 $HOME。sudo
在没有 . 的情况下运行时不保留用户的环境变量(包括$HOME
)-E
。,-E
它确实如此。顺便说一句,同样值得注意的是:虽然大多数 shell 可以并且确实可以扩展
~
为用户的主目录,但并非所有程序都可以。事实上,大多数程序都没有——这不是他们的工作,他们依赖 shell在看到任何参数之前执行波浪号和变量以及 glob 和其他扩展。问题:是否可以在 sudo-ed 命令中传递我的变量并评估 ~ 作为 /root ?
有几种方法,每种方法都有优点和缺点。这里是其中的一些:
unset HOME
在运行之前sudo -E
。HOME=/root
运行前设置sudo -E
。例如HOME=/root sudo -E bash -c 'echo $xx ~'
将要与 sudo 共享的变量写入文件。例如,您可以运行
declare -p var1 var2 var3 > /tmp/myvars.sh
并让sudo
(不-E
)运行一个 shell 脚本,该脚本source /tmp/myvars.sh
在运行您想要运行的任何内容之前执行sudo
。使用or中的
env_keep
设置- 这允许您定义在运行时将始终保留哪些变量,无论是否使用该选项。/etc/sudoers
/etc/sudoers.d/*
sudo
-E
(来自@MichaelHomer)使用
sudo
'-H
选项将 HOME 设置为目标用户的主目录并--preserve-env=xx
告诉 sudo 传递xx
变量(此选项采用逗号分隔的环境变量名称列表)。详情请参阅man sudo
。请注意,并非所有用户都有权保护环境。见man sudoers
。sudo
请注意,默认情况下不保留环境变量是有充分理由的。有许多 env vars 具有严重的安全隐患,并且滥用可能允许用户或组获得对他们不应访问的事物的 root(或其他 uid)访问权限。