什么是Login Shell和Non-Loin Shell?

经常看到一个概念“login shell”,或者叫登录shell,但很难从名称理解它的含义,从网上也很少找到详细的解释,今天来整理一下login shell的概念以及如何区分login shell和non-login shell。

哪些地方会看到Login Shell?

  • 使用ssh登录云服务器后,使用logout命令可以退出登录。但是使用docker exec -it xxx bash进入容器后,却不能使用logout退出,只能使用exit

    1
    2
    3
    [root@VM_0_14_centos mao]# docker exec -it b1a bash
    root@b1a87a169b90:/# logout
    bash: logout: not login shell: use `exit'
  • sudo命令有一个参数-i,用于运行一个login shell

    1
    2
    3
    4
    $ sudo --help
    ...
    -i, --login run login shell as the target user; a command may also be specified
    ...
  • su命令也有类似的参数:

    1
    2
    3
    4
    $ su --help
    ...
    -, -l, --login make the shell a login shell
    ...

login shell和非login shell有什么区别呢?别急,继续往下看。

Login Shell定义

先看一下login shell的定义[1]

A login shell is one whose first character of argument zero is a -, or one started with the –login option.

这段话每个单词都认识,放在一起就不知道什么意思。从句式可以看出意思是:

一个shell是login shell,要么【条件1】,要么【条件2】。

判断shell是login shell的第一个条件

先来看看条件1: first character of argument zero is a -,即一个shell的argument zero的第一个字符是个连字符”-“。在这里,argument zero其实指的是$0

$0是shell的一个参数,这个参数保存的是bash脚本的名称,bash初始化的时候会设置$0这个变量。与之类似的还有$$$*$#等等。

在bash中打印一下:

1
2
[root@mail ~]# echo $0
-bash

可以看到,打印出来脚本名称是-bash,第一个字符是”-“,说明这个是一个login shell。

使用ps命令查看进程,也可以看到bash的进程名称为-bash:

1
2
[root@mail ~]# ps aux|grep bash
root 28748 0.0 0.1 116500 3232 pts/0 Ss 22:51 0:00 -bash

如果打印出来第一个字符不是“-”, 例如:

1
2
$ echo $0
bash

也不能说明这不是login shell,还要看第二个条件。

判断shell是login shell的第二个条件

回到login shell的定义:

…or one started with the –login option.

后半句话就比较好理解,即shell启动的时候有--login参数

使用docker测试一下。不带--login参数:

1
2
3
[root@VM_0_14_centos ~]# docker exec -it b1a bash
root@b1a87a169b90:/# logout
bash: logout: not login shell: use `exit'

docker命令带上--login参数:

1
2
3
[root@VM_0_14_centos ~]# docker exec -it b1a bash --login
root@b1a87a169b90:/# logout
[root@VM_0_14_centos ~]#

可以看到,如果带上--login,那它就是一个login shell,可以使用logout退出shell。

Login Shell定义总结

如果一个shell的参数$0的第一个字符是连字符-,或者启动shell的时候有--login参数,那么这个shell就是一个login shell。

Login Shell和非 Login Shell有什么区别?

  • 启动shell时需要认证(密码、公钥等)的,一般是login shell,被其它进程调用启动的shell一般是 non-login shell(带上--login参数例外)。
  • (重点)login shell和非login shell加载的环境配置文件不同,所以通常它们的环境变量不同。

参考

  1. 英文Bash文档:login shell的定义