$ whoami
admin
$ sudo -S -u otheruser whoami
otheruser
$ sudo -S -u otheruser /bin/bash -l -c 'echo $HOME'
/home/admin
尽管 bash 作为登录 shell 被调用,但为什么没有$HOME
设置为?/home/otheruser
具体来说,/home/otheruser/.bashrc
没有来源。另外,/home/otheruser/.profile
还没有来源。 -(/home/otheruser/.bash_profile
不存在)
答案1
要调用登录 shell,sudo
只需使用-i
.当未指定命令时,您将收到登录 shell 提示,否则您将获得命令的输出。
示例(登录 shell):
sudo -i
示例(使用指定用户):
sudo -i -u user
示例(带有命令):
sudo -i -u user whoami
示例(打印用户的$HOME
):
sudo -i -u user echo \$HOME
注意:反斜杠字符可确保美元符号到达目标用户的 shell,并且不会在调用用户的 shell 中进行解释。
我刚刚检查了最后一个例子斯特雷斯它准确地告诉您发生了什么。下面的输出显示正在--login
使用指定的命令调用 shell,就像显式调用 bash 一样,但除此之外须藤可以做自己的工作,例如设置$HOME
.
# strace -f -e process sudo -S -i -u user echo \$HOME
execve("/usr/bin/sudo", ["sudo", "-S", "-i", "-u", "user", "echo", "$HOME"], [/* 42 vars */]) = 0
...
[pid 12270] execve("/bin/bash", ["-bash", "--login", "-c", "echo \\$HOME"], [/* 16 vars */]) = 0
...
我注意到您正在使用-S
,但我认为这通常不是一种好的技术。如果您想以其他用户身份运行命令而不通过键盘执行身份验证,则可能需要使用 SSH。它适用localhost
于其他主机,并提供无需任何交互式输入即可工作的公钥身份验证。
ssh user@localhost echo \$HOME
注意:对于 SSH,您不需要任何特殊选项,因为 SSH 服务器始终创建一个可供 SSH 客户端访问的登录 shell。
答案2
你对 Bash 的信任太多了。所有“登录 shell”对于 Bash 来说都是在启动和关闭时获取的文件。该$HOME
变量不计入其中。
Bash 文档进一步解释了登录 shell 的含义:https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html#Bash-Startup-Files
$HOME
事实上,Bash根本不做任何设置。$HOME
由调用 shell 的任何内容(登录、ssh 等)设置,并且 shell 继承它。无论以 admin 设置$HOME
然后 exec-ed启动您的 shell bash
,sudo
从设计上看都不会改变环境,除非要求或配置这样做,以便bash
其他用户从您的 shell 继承它。
如果您想sudo
以您期望的方式处理更多环境,请查看-i
sudo 开关。尝试:
sudo -S -u otheruser -i /bin/bash -l -c 'echo $HOME'
sudo 的手册页对此进行了更详细的描述,但我认为不是很好:http://linux.die.net/man/8/sudo
答案3
sudo -u www-data bash -i -c "env"
请注意该-i
标志,它告诉 bash 以交互方式运行。
此命令将为 user 执行交互式 bash shell www-data
,在该 shell 中(作为示例)env
执行该命令。
即使用户www-data
有诺登录shell 作为默认 shell。