交互式shell,指的是你可以输入命令并获得执行结果的shell。而非交互式shell,一般是执行一个命令、一个脚本的shell,它们通常不需要人工干预,例如系统维护脚本、后台脚本等。
本文基于Bash总结一下交互式shell的定义和与非交互式shell的区别。
交互式定义
交互式shell定义:
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. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to
test this state.
option和argument是什么?
上面这段英文定义里面有一个“non-option arguments”比较难理解。在Linux中,命令行使用空格分割为一个个的argument
,例如:
以上图为例,命令执行时,在ls
脚本的内部,可以使用$0
来获取到ls
这个字符串,同理,$1
可以获取到-l
,使用$2
来获取到-a
选项等等。“arguments”就是$0
, $1
, $2
….等等以空格分割命令行后的每个部分。
而-l
和-a
这种可以改变ls
命令的行为的,叫做选项(即option),它们一般会被写在命令使用文档中:
再回到交互式shell定义里面的non-option arguments
,指的是不属于选项的参数。
例如上述命令中,参数/path/to/folder
既不是-l
选项的值,也不是-a
选项的值,它不属于任何一个option,所以它是一个non-option arguments
。
交互式shell定义总结
弄明白了non-option arguments
的含义,再看交互式shell的定义就比较简单了,翻译如下:
交互式shell指的是没有【不属于任何选项的参数】也没有
-c
选项,并且标准输入流和错误流都连接到终端的shell,或者启动shell时有-i
选项的shell。如果一个shell是交互式shell,
$PS1
变量会被设置,且$-
变量包含i
字符,在shell脚本中可以使用这两个变量来判断当前shell是不是交互式shell。
非交互式shell
有了交互式shell的定义,反过来就是非交互式shell。
- shell启动时有
-c
选项的是非交互式shell - 标准输入流和错误流没有连接到终端的shell,例如系统启动脚本、维护脚本,它们不需要交互。
- 没有
$PS1
变量。 $-
变量中不包含i
字符。
验证一下
打开一个命令行窗口,打印$PS1
变量:
1 | [root@mail ~]# echo $PS1 |
有输出,说明当前shell是个交互式shell。再测试$-
:
1 | [root@mail ~]# echo $- |
输出中包含字符i
,也说明是个交互式shell。
使用bash命令的-c
选项来执行上述命令:
1 | [root@mail ~]# bash -c "echo \$PS1" |
$PS1
没有任何输出,$-
输出中也不包含字符i
,都能说明执行echo
命令的shell不是交互式shell。可以理解为,执行bash -c "echo \$-"
命令的时候,实际上由当前shell启动了一个非交互式shell,然后让这个非交互式去执行echo $-
命令。
最后,测试一下,启动shell时带有【不属于任务选项的参数】。
- 首先创建一个
test.sh
文件,写入以下内容:1
2
echo $- - 调用
bash
来执行这个脚本:从结果中可以看出:1
2
3
4[root@mail ~]# bash test.sh
hB
[root@mail ~]# bash -i test.sh
himB
- 使用
-i
选项时,是交互式shell, - 没有
-i
选项时,是非交互式shell。
有什么区别?
交互式shell和非交互式shell启动时会加载不同的环境配置文件,不同的配置文件会有不同的初始化脚本和环境变量。