登录 shell 在哪里定义?

登录 shell 在哪里定义?

我正在阅读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 特有的。例如,我是mkshshell 用户,它没有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 $SHELLsudo mkshsudo 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到我的mkshshell,并带有我为其设置的特征提示符。当然,由于这不是登录操作,因此bash它会报告 shell 是作为非登录 shell 实例生成的。但是,在我的例子中,您会看到那里$-没有字母l,如果那是登录 shell 实例,那里就会有字母。

最后,同样的想法适用于sudo susudo 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_shellon

答案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 选项。

相关内容