登录外壳在哪里定义?


16

我在看sudo -i/-s 这里的区别。使用命令后shopt,请注意all(sudo su/sudo -i/sudo -s$SHELL提供相同的结果,但shopt命令结果不同。

那么,如何定义登录和非登录外壳?

从哪里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:~$ 

须藤-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:~# 

须藤-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:~# 

7
一个问题是“ login shell”有两个含义:1.它是以特定方式启动并执行特定操作(例如阅读.profile或等效操作)的shell实例,以及2.应该在登录时启动的shell用户,/etc/passwd或与之等效的定义。$SHELL包含后者,您的shopt输出将处理前者。通常,当(2)中的shell在登录时启动时,它以(1)所需的特定方式启动,因此含义是混淆的。
大师

1
@muru的解释是一个很好的解释。例如,如果您从远程计算机SSH进入计算机。您系统上的/ usr / sbin / sshd会派生一个由$SHELL(定义的)外壳程序(并将其连接到伪终端),该外壳程序又在您的/ etc / passwd条目中定义。此Shell是登录Shell,可以使用进行测试if [[ -o login ]]; then echo "I am a login shell"; fi。作为登录shell,它将执行适合于新会话的那些任务。例如源代码~/.zprofile或类似代码,它们可能会设置环境变量以及您此时可能希望运行的任何自定义外壳程序代码
the_velour_fog

Answers:


17

TL; DR

  • 登录外壳在哪里定义?在中/etc/passwd
  • sudo su/ sudo su -/ sudo -i/ sudo -s一样的吗?不,它们都产生了一个壳,但是在不同的上下文中它们是不同的。
  • 怎么$SHELL办?只需说出您的默认外壳,即可/etc/passwd

实际答案

首先,必须要提到的shopt是bash特定的。例如,我是mkshshell用户,并且没有shopt,就像ksh没有。

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

login_shell

如果外壳程序作为登录外壳程序启动,它将设置此选项

这就是关键。sudo -i正如您从阅读的上一个答案中已经知道的那样,应该模拟初始登录。这就是为什么shopt报告login_shell on 此选项的原因。可以认为这似乎sudo -i迫使外壳程序通过仅在登录过程中出现的文件(这些文件不会从交互式外壳程序获取)。

在其他情况下,您已经在运行外壳程序的实例,因此它首先不能是登录外壳程序,并且选项的目的有所不同。sudo -s仅读取$SHELL(旨在表示您在中设置的默认shell /etc/passwd)变量并以root特权运行它。这等效于执行sudo $SHELLor sudo 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因此它会报告该外壳作为非登录外壳实例生成。但是,在我的情况下,您会看到那里$-没有字母l,如果这是一个登录shell实例,那么该字母就在那里。

最后,同样的想法适用于sudo susudo su -。后面的一个生成登录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

至于登录外壳程序和非登录外壳程序之间的区别,此答案中 unix.stackexchange.com上备受推崇的Gilles 对此进行了解释


额外的乐趣

您可以尝试一些有趣的事情。您可能已经知道,登录外壳程序将运行.profile(并且已配置.bashrc Ubuntu .profile 这样做),但非登录地狱将仅运行.bashrc文件。因此,我们可以测试其中echo哪些命令运行登录外壳程序,哪些不运行登录外壳程序,并且我们期望echo登录外壳程序使用两行,非登录使用仅一行。

$ 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


谢谢@Serg和@Zanna。现在,$SHELLlogin_shell/non-login_shell得到澄清。但是从哪里shopt获取详细信息?是从哪里来的echo $0
prado

1
@prado我会说是,因为第一个字符$0用于指定外壳程序是否为登录外壳程序,因此如果shopt要检查该变量,可以肯定,这是完全可以接受的。但是,可能还不止这些。shopt可能对于这个问题,我没有一个硬性的答案,因为我不太熟悉bash的源代码。
Sergiy Kolodyazhnyy

通过将$ 0的第一个字符设为be -或使用该-l选项,可以将@prado Bash作为登录shell启动。
大师

@prado可以在手册页中了解有关bash的调用和选项的信息。例如,SHELL BUILTIN COMMAND的部分说,login_shell The shell sets this option if it is started as a login shell (see INVOCATION above). The value may not be changed.所以shopt login_shellbash似乎是让您找出的一种方式-以编程方式如何知道它是如何开始的。另一种方式是[[ -o login ]]
the_velour_fog

11

正如@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,是SH ELL 选择离子在shell启动的时间确定。Shell程序将这些信息及其所有其他设置和变量一起存储。该shopt命令提供了一种查看此信息的方法,并在可能的情况下(如果可能的话)设置或取消设置此信息(login_shell当然,情况并非如此,这取决于启动外壳程序的过程)

sudo程序的选项确定如何启动这些不同类型的根外壳程序:

在此处输入图片说明


1
很好的解释。我认为您已经解释了什么shoptlogin_shell并且应该比我的回答更好。
Sergiy Kolodyazhnyy

@Serg谢谢:)我认为您的解释更加彻底:)
Zanna

3

man bash

登录外壳是一个参数为零的第一个字符为 -,或一个以该--login选项开头的。

man login

的值$HOME$SHELL [...]根据在密码输入相应的字段设置。

简而言之:

  • 如果外壳程序是作为登录外壳程序调用的,则它是登录外壳程序。
  • 环境变量由调用程序$SHELL设置,login也可以由调用程序设置,例如su。外壳本身不会设置它。
  • shopt 显示当前有效的shell选项。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.