登录shell在哪里定义?

pra*_*ado 16 command-line bash sudo

我正在阅读sudo -i/-s 此处之间的差异。使用命令后shopt注意到 all( 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:~$ 
Run Code Online (Sandbox Code Playgroud)

须藤 -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:~# 
Run Code Online (Sandbox Code Playgroud)

须藤 -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:~# 
Run Code Online (Sandbox Code Playgroud)

Ser*_*nyy 17

特尔;博士

  • 登录外壳在哪里定义?在/etc/passwd.
  • sudo su/ sudo su -/ sudo -i/sudo -s一样的吗?不,它们都产生了一个壳,但在不同的上下文中不同。
  • 有什么作用$SHELL?只需告诉您的默认 shell,与/etc/passwd.

实际答案

首先,重要的是要提到它shopt是特定于bash 的。例如,我是mkshshell 用户,它没有shopt,就像ksh没有一样。

接下来,究竟login_shell应该代表什么?来自man bash

登录_shell

如果 shell作为登录 shell 启动,则会设置此选项

这就是关键点。sudo -i,正如您从之前阅读的答案中已经知道的那样,应该模拟初始登录。这就是shopt报告login_shell on 此选项的原因。将此视为sudo -i强制外壳程序通过应该仅在登录过程中出现的文件(这些文件不是由交互式外壳程序提供的)。

在其他情况下,您已经在运行 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
Run Code Online (Sandbox Code Playgroud)

你看到的是sudo -sbash我的mkshshell跳转到我的shell,带有我为它设置的特征提示。当然,由于它不是登录操作,因为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
Run Code Online (Sandbox Code Playgroud)

所以从技术上讲,shopt login_shell没有任何关系$SHELL。这样想:它的目的是展示bash是如何运行的。$SHELL应该只反映您在/etc/passwd.

至于登录shell和非登录shell的区别,unix.stackexchange.com上备受推崇的Gilles在这个回答中已经解释过了。


额外的乐趣

这里有一些有趣的东西你可以试试。您可能已经知道,登录 shell 将运行.profile(并且.bashrc因为 Ubuntu 的.profile 配置是这样做的),但非登录地狱将仅运行.bashrc文件。所以我们可以测试echo哪些命令运行登录shell,哪些不运行,我们期望两行echo用于登录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:~# 
Run Code Online (Sandbox Code Playgroud)

适当地,具有两行输出的那些将login_shell设置为on.


Zan*_*nna 11

正如@Serg在这个关于如何判断您正在运行的 shell 的答案中所解释的那样,该SHELL变量只是从以下位置读取的当前用户的默认shell /etc/passwd

$ grep zanna /etc/passwd
zanna:x:1000:1000:Zanna,,,:/home/zanna:/bin/bash
Run Code Online (Sandbox Code Playgroud)

所以如果我echo $SHELL总是会返回/bin/bash

$ zsh
% echo $SHELL
/bin/bash
Run Code Online (Sandbox Code Playgroud)

无论shell是一个登录shell,是SH ELL选择离子在shell启动的时间确定。Shell 程序将这些信息与其所有其他设置和变量一起存储。该shopt命令提供了一种查看此信息的方法,并在可能的情况下对相关选项进行设置或取消设置(login_shell当然,情况并非如此,这取决于用于启动 shell 的进程)

sudo程序的选项确定这些不同类型的root shell中如何将开始:

在此处输入图片说明