我正在阅读sudo -i/-s
这里。使用命令后,shopt
注意到所有(sudo su/sudo -i/sudo -s
)$SHELL
都提供相同的结果,但shopt
命令结果不同。
那么,登录和非登录shell是如何定义的?
从哪里shopt
得到结果?
为什么它与之不相关$SHELL
?
须藤苏
givinv@87-109:~$ sudo su
root@87-109:/home/givinv#
root@87-109:/home/givinv#
root@87-109:/home/givinv# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:/home/givinv# echo $SHELL
/bin/bash
root@87-109:/home/givinv#
root@87-109:/home/givinv# exit
givinv@87-109:~$
sudo-i
givinv@87-109:~$ sudo -i
root@87-109:~#
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
Login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~#
sudo -s
root@87-109:~# sudo -s
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~#
答案1
总结:
- 登录 shell 在哪里定义?在
/etc/passwd
。 sudo su
/sudo su -
/sudo -i
/一样吗sudo -s
?不,它们都会生成一个 shell,但是方式不同,并且处于不同的上下文中。- 做什么
$SHELL
?只需告知您的默认 shell,与 中相同/etc/passwd
。
实际答案:
首先,需要指出的是,这shopt
是 bash 特有的。例如,我是mksh
shell 用户,它没有shopt
,就像ksh
没有一样。
接下来,到底login_shell
应该代表什么?来自man bash
:
登录外壳
shell 设置此选项 如果它作为登录 shell 启动
这是关键点。sudo -i
正如您从前面的回答中已经知道的那样,它应该模拟初始登录。这就是shopt
报告login_shell on
此选项的原因。可以将其视为sudo -i
强制 shell 浏览仅在登录过程中出现的文件(不会由交互式 shell 获取)。
在其他情况下,您已经在运行 shell 的实例,因此它首先不能是登录 shell,并且选项的用途也不同。sudo -s
仅读取$SHELL
(用于表示您在 中设置的默认 shell /etc/passwd
)变量并以 root 权限运行它。这相当于执行sudo $SHELL
或sudo mksh
或sudo bash
(无论您使用哪个)。
还记得我提到过我是mksh
用户吗?看一下这个:
$ bash --posix
bash-4.3$ sudo -s
[sudo] password for xieerqi:
DIR:/xieerqi|01:53|skolodya@ubuntu:
$ id
uid=0(root) gid=0(root) groups=0(root)
DIR:/xieerqi|01:53|skolodya@ubuntu:
$ echo $-
imsU
您看到的是sudo -s
从 跳转bash
到我的mksh
shell,并带有我为其设置的特征提示符。当然,由于这不是登录操作,因此bash
它会报告 shell 是作为非登录 shell 实例生成的。但是,在我的例子中,您会看到那里$-
没有字母l
,如果那是登录 shell 实例,那里就会有字母。
最后,同样的想法适用于sudo su
和sudo su -
。后者生成登录 shell 实例(即,将运行登录所需的特定文件),而前者仅生成交互式 shell(即,不运行登录文件)。
bash-4.3$ sudo su
[sudo] password for xieerqi:
root@eagle:/home/xieerqi# shopt login_shell
login_shell off
root@eagle:/home/xieerqi# exit
bash-4.3$ sudo su -
[sudo] password for xieerqi:
$ shopt login_shell
login_shell on
所以从技术上讲,shopt login_shell
与任何事情都没有任何关系$SHELL
。这样想:它的目的是展示如何bash 运行。$SHELL
应该只反映您在中分配的内容/etc/passwd
。
至于登录 shell 和非登录 shell 之间的区别,unix.stackexchange.com 上备受尊敬的 Gilles 已经在这个答案。
额外的乐趣
你可以尝试一些有趣的东西。你可能已经知道,登录 shell 将运行.profile
(.bashrc
因为 Ubuntu 的.profile
配置为这样做),但 non-logins hell 将仅运行.bashrc
文件。因此,我们可以测试echo
这些命令中的哪一个运行登录 shell,哪一个不运行,并且我们期望echo
登录 shell 有两行,非登录 shell 只有一行。
$ echo "echo 'hi,i am .profile'" >> .profile
$ echo "echo 'hi, i am .bashrc'" >> .bashrc
$ sudo -i
hi, i am .bashrc
hi,i am .profile
$ sudo su
hi, i am .bashrc
root@eagle:~# sudo su -
hi, i am .bashrc
hi,i am .profile
$ sudo -s
hi, i am .bashrc
root@eagle:~#
相当恰当的是,那些具有两行输出的将设置login_shell
为on
。
答案2
正如@Serg 解释的那样在这个关于如何判断你正在运行什么 shell 的答案中,SHELL
变量只是当前用户的默认shell 读取自/etc/passwd
:
$ grep zanna /etc/passwd
zanna:x:1000:1000:Zanna,,,:/home/zanna:/bin/bash
所以如果我echo $SHELL
它总是会返回/bin/bash
:
$ zsh
% echo $SHELL
/bin/bash
无论 shell 是否是登录 shell,什艾尔选择在启动 shell 时确定的 ion。shell 程序将此信息与其所有其他设置和变量一起存储。该shopt
命令提供了一种查看此信息的方法,并且如果可能的话,可以针对相关选项设置或取消设置它(login_shell
当然,这不是这种情况,这取决于用于启动 shell 的进程)
该sudo
程序的选项决定了如何启动这些不同类型的 root shell:
答案3
man bash
:
登录 shell 是参数零的第一个字符为 的 shell
-
,或者以--login
选项启动的 shell。
man login
:
$HOME
、 [...]的值$SHELL
根据密码条目中的相应字段进行设置。
简而言之:
- 如果某个 shell 被作为登录 shell 调用,那么它就是登录 shell。
- 环境变量
$SHELL
由或由调用程序设置login
,例如su
。shell 本身不会设置它。 shopt
显示当前有效的 shell 选项。