Wetts's blog

Stay Hungry, Stay Foolish.

0%

Linux-命令-交互式_非交互式_登录式_非登录式.md

转自:https://blog.csdn.net/sch0120/article/details/70226903

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,也就相当于执行指定的命令,它和前者有些类似,只是不从脚本文件中读取罢了。请看例子:

1
2
3
4
5
6
7
8
9
[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 选项:

1
2
3
4
[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,请看例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
[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 的则不好说。

1
2
3
4
[chen@localhost ~]$ bash --login
[chen@localhost ~]$ echo $0
bash
[chen@localhost ~]$

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

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

1
2
3
4
5
6
7
[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 的“登陆”属性,并分别调用 logout 或 exit 指令,因此使用起来相对方便。

主要区别

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

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