Bash 中的波形符扩展与变量

Bash 中的波形符扩展与变量

请考虑以下片段:

$ 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

答案1

您对波形符如何工作的理解并不完整。查看man bash并搜索Tilde Expansion.

它开头为(额外的换行符和我添加的一些粗体):

如果单词以不带引号的波形符 ( ~) 开头,则第一个不带引号的斜杠之前的所有字符(或所有字符,如果没有不带引号的斜杠)都被视为波形符前缀。

如果波形符前缀中的任何字符均未加引号,则波形符前缀中跟随波形符的字符将被视为可能的登录名。

如果此登录名是空字符串,则波浪号将替换为 shell 参数的值HOME如果HOME未设置,执行 shell 的用户的主目录将被替换。

否则,波形符前缀将替换为与指定登录名关联的主目录。

简而言之,~如果 $HOME 非空,则扩展为 $HOME。

sudo$HOME没有-E.有了-E,确实如此。

顺便说一句,还值得注意的是:虽然大多数 shell 可以并且确实扩展~为用户的主目录,但并非所有程序都这样做。事实上,大多数程序不这样做 - 这并不是他们真正的工作,他们依赖 shell 来执行波浪号、变量和 glob 以及其他扩展他们看到任何争论。


问题:是否可以在 sudo-ed 命令中传递我的变量并将 ~ 评估为 /root ?

有多种方法,每种方法都有优点和缺点。这里是其中的一些:

  1. unset HOME跑步前sudo -E

  2. HOME=/root运行前设置sudo -E。例如HOME=/root sudo -E bash -c 'echo $xx ~'

  3. 将要与 sudo 共享的变量写入文件。例如,您可以运行declare -p var1 var2 var3 > /tmp/myvars.shsudo(不-E)运行一个 shell 脚本,该source /tmp/myvars.sh脚本在运行您想要运行的任何内容之前执行此操作sudo

  4. 使用orenv_keep中的设置- 这允许您定义在运行时始终保留哪些变量,无论有或没有该选项。/etc/sudoers/etc/sudoers.d/*sudo-E

  5. (来自@MichaelHomer)使用sudo-H选项将 HOME 设置为目标用户的主目录并--preserve-env=xx告诉 sudo 传递xx变量(此选项采用逗号分隔的环境变量名称列表)。man sudo详情请参阅。请注意,并非所有用户都有权保护环境。看man sudoers

sudo请注意,默认情况下不保留环境变量是有充分理由的。有许多环境变量具有严重的安全隐患,并且滥用可能会允许用户或组获得 root(或其他 uid)访问权限,以访问他们不应访问的内容。

相关内容