如何使sudo执行echo命令时输出root?Bash变量求值技术咨询
你猜的完全没错!问题的核心就是变量展开的时机:当你运行sudo echo "I am $USER"!时,你的普通用户shell会先一步把$USER解析成你的用户名,然后才把已经替换好的字符串I am my-username!传给sudo执行。所以echo拿到的是现成的文本,自然不会输出root的用户名。
要让$USER在root环境下被解析,我们需要让root的shell来处理变量展开,而不是当前的普通用户shell。这里有几种实用的解决方法:
方法1:用单引号包裹命令,阻止当前shell解析变量
通过sudo启动一个bash(或sh)进程,把要执行的命令用单引号包起来——单引号会让当前shell完全不解析里面的变量,把完整的命令字符串原封不动传给root的shell,由它来展开$USER:
sudo bash -c 'echo "I am $USER!"'
执行这个命令,你就能看到I am root!的输出了。
方法2:转义$符号,保留变量给root shell解析
如果你更习惯用双引号,可以在$前面加反斜杠\,告诉当前shell:“这个$不要解析,原样传下去”。同时注意转义内部的双引号,避免提前闭合外层的双引号:
sudo bash -c "echo \"I am \$USER!\""
这种写法和方法1效果完全一样,只是语法上的偏好不同。
方法3:临时切换到root交互式shell(适合多命令测试)
如果你不止要执行这一条echo命令,而是想测试多个root环境下的变量操作,直接切换到root的交互式shell更方便:
sudo -i
进入root环境后,直接输入echo "I am $USER!",自然会输出I am root!。完成测试后输入exit就能回到普通用户环境。
补充一句:你提到的sudo env能看到root环境,是因为env是直接在root环境中执行的,没有经过当前shell的变量替换步骤,所以它输出的是root的完整环境变量列表。
内容的提问来源于stack exchange,提问作者jaaq

