2

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

 3 years ago
source link: https://wetts.github.io/2020/03/14/%E7%B3%BB%E7%BB%9F&%E6%9C%8D%E5%8A%A1%E5%99%A8/Linux/Linux-%E5%91%BD%E4%BB%A4-%E4%BA%A4%E4%BA%92%E5%BC%8F_%E9%9D%9E%E4%BA%A4%E4%BA%92%E5%BC%8F_%E7%99%BB%E5%BD%95%E5%BC%8F_%E9%9D%9E%E7%99%BB%E5%BD%95%E5%BC%8F/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK