什么是子Shell
子Shell的概念其实是贯穿整个Shell的,如果想要更好的理解和写Shell脚本则必须要了解子Shell的相关知识。其概念如下所示:
子Shell本质就是从当前的Shell环境中打开一个新的Shell环境,而新开的Shell称之为子Shell(SubShell),相应的开启子Shell的环境称之为父Shell。子Shell和父Shell是子进程和父进程的关系,而这个进程则全部是bash进程。子Shell可以从父Shell中继承变量、命令全路径、文件描述符、当前工作目录等。在子Shell中常用的两个变量如下所示:
$BASH_SUBSHELL:查看从当前进程开始的子Shell层数
$BASHPID:查看当前所处BASH的PID
在Linux系统中,系统运行的程序基本都是从CentOS 6.x(init)或CentOS7.x(systemd)PID为1的进程)继承而来的,所有的程序都可以看作为init的子进程。
# CentOS 6.x
[root@localhost data]# pstree -hp
init(1)─┬─NetworkManager(3643)
├─Xvnc(22811)
├─abrtd(4760)
├─acpid(3755)
├─atd(4801)
├─auditd(3392)───{auditd}(3393)
├─automount(3849)─┬─{automount}(3850)
│ ├─{automount}(3851)
│ ├─{automount}(3854)
│ └─{automount}(3857)
# CentOS 7.x
[root@localhost ~]# pstree -hp
systemd(1)─┬─ModemManager(1051)─┬─{ModemManager}(1068)
│ └─{ModemManager}(1076)
├─Xvnc(5563)─┬─{Xvnc}(5566)
│ ├─{Xvnc}(5567)
│ ├─{Xvnc}(5568)
子Shell产生的途径
通过后台作业:&
[root@localhost Test]# cat jobs.sh
#!/bin/bash
parentShell="ParentShell"
echo "Parent Shell start and Level:"$BASH_SUBSHELL
# define subshell
{
echo "SubShell start and Level:"$BASH_SUBSHELL
subShell="SubShell"
echo "SubShell value: ${subShell}"
echo "parentShell value: ${parentShell}"
# sleep 5
echo "SubShell end and Level: $BASH_SUBSHELL "
} & # running in backgroud
echo "Parent end and Level:$BASH_SUBSHELL"
if [ -z "${subShell}" ]
then
echo "subShell is not defined in ParentShell"
else
echo "subShell is defined in ParentShel"
fi
[root@localhost Test]# bash jobs.sh
Parent Shell start and Level:0
Parent end and Level:0
subShell is not defined in ParentShell
SubShell start and Level:1
SubShell value: SubShell
parentShell value: ParentShell
SubShell end and Level: 1
根据运行结果,结论如下所示:
在Shell中可以使用&产生子Shell
由&产生的子Shell可以直接引用父Shell的变量,而子Shell产生的变量不能被父Shell引用
在Shell中使用&可以实现多线程并发