1. 所谓子shell,即从当前shell 环境中新开了一个shell 环境,这是新开的shell环境就是子shell ,而开启子shell的环境称为该子shell的父shell.子shell和父shell的关系,就是子进程和父进程的关系,只是这个关联的进程是bash进程。
子shell 会从父shell 中继承很多环境变量如:变量 文件描述符 当前工作目录 陷阱等。
不同的子shell继承环境不相同,变量 $BASH_SUBSHELL 可以查看从当前进程开始的子shell的层级数,$BASHPID 查看当前BASH的pid .
子shell 类型
1 fork 是复制进程,它会复制当前进程的副本,从父进程那继承了一些资源,这些资源包括内存中的内容,环境变量和变量,但是他和父进程是完全独立的,他们是一个程序的两个实例。
2 exec 是加载另一个应用程序,替代当前运行的进程,也就是在不创建新的进程的情况下加载一个新进程,在进程执行完全后退出所在的shell环境。为了保证进程的安全,新的且独立的子进程,内容和父进程是一样的(包括变量)
什么时候进入子shell环境,什么时候不进入子shell环境?
1 bash 内置命令 bash的内置命令默认是不开启子shell的,而是直接在当前bash 的环境中执行的,但是如果内置命令放在管道后,则此内置命令将管道左边的进程属于一个进程组,所以会创建子shell。
2 前面说过 bash 命令默认是不开启子进程的,但是bash 命令是个例外,他的情况比较特殊,他做为一个内置命令默认不开启子shell ,但是他命令本身要调用环境变量,使用本身的环境变量来清空了本地变量。所以看上去就会觉得他开了子shell ,从这个角度来说他又开了子进程。说清楚了以上两点就能理解下面命令的执行结果了
![](https://s1.51cto.com/images/blog/201905/22/01ddf7c1c9d3c52786634961d598830f.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
小括号开启了子进程,但是变量TITLE继承了父进程的值,所以第二个echo 执行的结果是ceo ,第三个中重新赋值了,则输出的结果是coo ,当退出了子进程,子进程的环境变量被回收,此时加载父进程自身的环境,此时在执行是结果 是ceo .
{} 不开启子进程 所以以上执行的结果是 mage wang wang
() 开启了子进程,所以执行结构是mage wang mage
以上所有皆为借鉴了https://blog.csdn.net/m0_37556444/article/details/83090602
该作者的文章加上自己的理解,解决自己问题,以上仅供参考。
转载于:https://blog.51cto.com/2858259639/2398725