关于“交互式-非交互式”与“登录-非登陆”shell的总结

运行中bash具有的两种属性

Linux shell是用户与Linux系统进行交互的媒介,而bash作为目前Linux系统中最常用的shell,它在运行时具有两种属性,即“交互”与“登陆”。

按照bash是否与用户进行交互,可以将其分为“交互式”与“非交互式”;而按照bash是否被用户登陆,又可将其分为“登陆shell”与“非登陆shell”。

“交互式”与“非交互式”

含义说明

交互式,是shell的一种运行模式,交互式shell等待你输入命令,并且立即执行,然后将结果反馈给你。这是每个CLI用户都非常熟悉的流程:登录、执行一些命令、登出。当你登出后,这个shell就终止了。

而非交互式,是shell的另一种运行模式,它专门被用来执行预先设定的命令。在这种模式下,shell不与用户进行交互,而是读取存放在脚本文件中的命令并执行它们。当它读到文件的结尾,这个shell就终止了。

启动方法

根据bash手册上的描述:

An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.

从上面的描述看,只要执行bash命令的时候,不带有“选项以外的参数”或者-c选项,就会启动一个交互式shell。要理解这句话,就要弄懂“选项以外的参数”是什么意思,其实它指的就是shell的脚本文件;而-c选项将指定字符串作为命令读入bash,也就相当于执行指定的命令,它和前者有些类似,只是不从脚本文件中读取罢了。请看例子:

[chen@localhost Temp]$ echo "uname -r; date" > script.sh
[chen@localhost Temp]$ bash ./script.sh 
3.10.0-514.el7.x86_64
Tue Apr 18 14:43:50 CST 2017
[chen@localhost Temp]$ 
[chen@localhost Temp]$ bash -c "uname -r; date"
3.10.0-514.el7.x86_64
Tue Apr 18 14:44:49 CST 2017
[chen@localhost Temp]$ 

通常来说,用于执行脚本的shell都是“非交互式”的,但我们也有办法把它启动为“交互式”shell,方法就是在执行bash命令时,添加-i选项:

[chen@localhost Temp]$ bash -c "echo \$-"
hBc
[chen@localhost Temp]$ bash -i -c "echo \$-"
himBHc

我们看到,添加了-i选项的bash -c命令为我们启动了一个“交互式”shell。

判别方法

根据bash手册上的描述:

PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.

用于在shell脚本和startup文件中判断当前shell“交互”属性的方法,就是判断变量PS1是否有值,或者判断变量$-是否包含i,请看例子:

[chen@localhost Temp]$ cat ./test1.sh 
echo "\$0   : $0"
echo "\$-   : $-"
echo "\$PS1 : $PS1"
[chen@localhost Temp]$ bash ./test1.sh     # 非交互式shell
$0   : ./test1.sh
$-   : hB
$PS1 : 
[chen@localhost Temp]$ bash -i ./test1.sh  # 交互式shell
$0   : ./test1.sh
$-   : himB
$PS1 : [\u@\h \W]\$ 
[chen@localhost Temp]$ 

“登陆shell”与“非登陆shell”

含义说明

“登陆shell”通常指的是:
1. 用户通过输入用户名/密码(或证书认证)后启动的shell;
2. 通过带有-l|--login参数的bash命令启动的shell。
例如,系统启动、远程登录、使用su -切换用户、通过bash --login命令启动bash等。

而其他情况启动的shell基本上就都是“非登陆shell”了。
例如,从图形界面启动终端、使用su切换用户、通过bash命令启动bash等。

判别方法

根据bash手册上的描述:

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

我们可以通过在shell中echo $0查看,显示-bash的一定是“登陆shell”,反之显示bash的则不好说。

[chen@localhost ~]$ bash --login
[chen@localhost ~]$ echo $0
bash
[chen@localhost ~]$ 

可以看出,使用bash --login启动的“登陆shell”,其$0也并非以-开头,这也就是为什么手册上的描述里使用“or”的原因。

另外,当我们执行exit命令退出shell时,也可以观察到它们的不同之处:

[chen@localhost ~]$ bash --login
[chen@localhost ~]$ exit   # 退出登陆shell
logout
[chen@localhost ~]$ bash
[chen@localhost ~]$ exit   # 退出非登陆shell
exit
[chen@localhost ~]$ 

原则上讲,我们使用logout退出“登陆shell”,使用exit退出“非登录shell”。但其实exit命令会判断当前shell的“登陆”属性,并分别调用logoutexit指令,因此使用起来相对方便。

主要区别

对于用户而言,“登录shell”和“非登陆shell”的主要区别在于启动shell时所执行的startup文件不同

简单来说,“登录shell”执行的startup文件为~/.bash_profile,而“非登陆shell”执行的startup文件为~/.bashrc

关于bash的startup文件,请参阅我的另一篇博客:
《关于“.bash_profile”和“.bashrc”区别的总结》

你可能感兴趣的:(Liunx)