在 Ubuntu 12.04 上,当我的sudo -s
$HOME 变量没有改变时,所以如果我的普通用户是regularuser
,情况会是这样的:
$ cd
$ pwd
/home/regularuser
$ sudo -s
# cd
# pwd
/home/regularuser
我很久以前就放弃了 Ubuntu,所以我不能确定,但我认为这是默认行为。所以,我的问题是:
- 这是怎么做到的?配置在哪里?
- 我如何禁用它?
编辑: 感谢您的答案,这使事情变得更加清晰,但我想我必须添加几个问题,才能得到我正在寻找的答案。
- 在 Debian 中
sudo -s
,将 $HOME 变量更改为/root
.从我从答案和man sudo
运行的 shell 中得到的结果sudo -s
是 中给出的/etc/passwd
,对吗? /etc/passwd
然而,在 Ubuntu 和 Debian 上,root 的shell都是/bin/bash
.在这两个系统中,就 $HOME 而言,我也找不到.profile
或文件的差异在哪里,因此 的行为有所不同。对此有什么帮助吗?.bashrc
sudo -s
答案1
Sudo 有许多编译时配置选项。您可以使用 列出您的版本中的设置sudo -V
。 Debian wheezy 和 Ubuntu 12.04 中的配置之间的差异之一是HOME
Ubuntu 中保留了环境变量,但 Debian 中不保留;两个发行版都会删除所有环境变量,除了一些明确标记为安全保存的环境变量。因此在 Ubuntu 上sudo -s
保留,而在 Debian 上则被删除,然后将其设置为目标用户的主目录。HOME
HOME
sudo
您可以在sudoers
文件。运行visudo
以编辑sudoers
文件。有几个相关选项:
env_keep
确定保留哪些环境变量。用于Defaults env_keep += "HOME"
保留调用者的HOME
环境变量或Defaults env_keep -= "HOME"
删除它(并用目标用户的主目录替换它)。env_reset
确定是否重置环境变量。对于允许运行特定命令的规则来说,重置环境变量通常是必要的,但对于允许运行任意命令的规则来说,重置环境变量并没有直接的安全优势。always_set_home
如果设置,HOME
即使由于env_reset
被禁用或HOME
位于env_keep
列表中而被保留,也会被覆盖。如果HOME
不保留此选项则无效。set_home
类似于always_set_home
,但仅适用于sudo -s
,不适sudo
用于使用显式命令调用时。
可以为给定的源用户、给定的目标用户或给定的命令设置这些选项;sudoers
详细信息请参阅手册。
您始终可以通过传递 option来选择覆盖HOME
给定的调用。sudo
-H
shell 永远不会覆盖 的值HOME
。 (HOME
如果未设置,它会设置,但sudo
总是HOME
以一种或另一种方式设置。)
如果您运行sudo -i
,sudo
则会模拟初始登录。这包括设置HOME
目标用户的主目录并调用登录外壳。
答案2
使用sudo -H -i
而不是sudo -s
获取交互式登录 root shell:
sudo -H -i
cd
pwd -P # /private/var/root (on Mac OS X 10.6.8)
从man sudo
:
-H The -H (HOME) option sets the HOME environment variable to
the homedir of the target user (root by default) as
specified in passwd(5). By default, sudo does not modify
HOME (see set_home and always_set_home in sudoers(5)).
答案3
这与“登录 shell”和“非登录 shell”的行为关系不大sudo
,而与“登录 shell”和“非登录 shell”之间的差异有很大关系。快速解决方法是
$ sudo -i
可以看出:
$ sudo -s
# id
uid=0(root) gid=0(root) groups=0(root)
# echo $HOME
/home/msw
# exit
$ sudo -i
# echo $HOME
/root
# pwd
/root
正如 sudo 手册中所述:
-i(模拟初始登录)选项将目标用户的密码数据库条目指定的 shell 作为登录 shell 运行。这意味着 shell 将读取特定于登录名的资源文件,例如 .profile 或 .login。如果指定了命令,则会通过 shell 的 -c 选项将其传递到 shell 执行。如果未指定命令,则执行交互式 shell。
答案4
要分别摆脱sudo -s
Ubuntu 和 Debian 上的不同行为,您可以使用sudo
包装器(问题 4 的答案):
sudos() {
local PATH="$(getconf PATH)" root_homedir
root_homedir="$(sudo -H sh -c 'printf "%s" "$HOME"')"
sudo sh -c 'export HOME="$0"; exec sh -i' "$root_homedir"
return 0
}
sudo -k
sudos
{
logname
whoami
id -un
id -ur
echo "PATH: $PATH"
}
exit
echo "PATH: $PATH"