经常看到一个概念“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 | [root@mail ~]# echo $0 |
可以看到,打印出来脚本名称是-bash
,第一个字符是”-“,说明这个是一个login shell。
使用ps
命令查看进程,也可以看到bash的进程名称为-bash
:
1 | [root@mail ~]# ps aux|grep bash |
如果打印出来第一个字符不是“-”, 例如:
1 | $ echo $0 |
也不能说明这不是login shell,还要看第二个条件。
判断shell是login shell的第二个条件
回到login shell的定义:
…or one started with the –login option.
后半句话就比较好理解,即shell启动的时候有--login
参数。
使用docker测试一下。不带--login
参数:
1 | [root@VM_0_14_centos ~]# docker exec -it b1a bash |
docker命令带上--login
参数:
1 | [root@VM_0_14_centos ~]# docker exec -it b1a bash --login |
可以看到,如果带上--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加载的环境配置文件不同,所以通常它们的环境变量不同。