Linux中父shell 与 子shell
子Shell概念
实际上子Shell有两种,一种是subshell(子Shell),一种是child shell(子进程Shell)
Subshell
subshell 是指通过启动一个新的Shell进程来执行命令或脚本时,这个子Shell是父Shell的一个拷贝。也就是说,它会继承父Shell的环境(包括变量、函数、别名等),但是它对环境变量、函数、别名等的修改只在该subshell内有效,不会影响到父Shell。
基本命令执行
- echo $BASH_SUBSHELL:这个命令用于显示当前的 BASH 子 shell 层级。初始值为 0,表示当前处于主 shell 环境。
- (echo $BASH_SUBSHELL):这是进入 1 层子 shell 的操作。执行后,$BASH_SUBSHELL的值变为 1。
- ((echo $BASH_SUBSHELL)):这是尝试进入 4 层子 shell 的操作,但由于语法错误(-bash: ((: ((echo 0)): missing ')' (error token is "0")))导致报错。
分析:
((...)) 通常用于算术运算和条件判断,而你在其中使用了 echo 0,这是不恰当的。它期望的是一个算术表达式,而不是一个命令。
子 shell 和进程层级
- 首先,重复了echo $BASH_SUBSHELL的操作,确认当前的子 shell 层级。
- bash命令:执行这个命令会进入一个新的 shell(child shell),$BASH_SUBSHELL的值变为 1,表示进入了 1 层子 shell。
- echo $SHLVL:这个命令用于显示当前的 shell 层级($SHLVL),初始值为 1,进入子 shell 后变为 2。
- 多次执行bash和echo命令,展示了如何进入更深层的子 shell,并观察$BASH_SUBSHELL和$SHLVL的变化。
我们来看看subshell和child shell的区别:
child shell是一个全新的环境,不共享父shell中的普通变量,普通变量只能通过export方式实现共享。
subshell 中的普通变量是可以从父shell中继承的,只是不能改变父shell中的变量值。
我们来验证一下
验证环境:
见下图:
- 显示 shell 进程号
- echo $$:这行命令用于显示当前 shell 的进程号(PID),结果为 3080。
- 子 shell 操作
- (echo $$; echo $x; ps; x=5; echo $x):这是一个在子 shell 中执行的命令组。
- echo $$:在子 shell 中显示子 shell 的进程号,结果为 3080。
- echo $x:在子 shell 中输出变量x的值,结果为 10。
- ps:显示当前系统中的进程列表。
- x=5:在子 shell 中将变量x赋值为 5。
- echo $x:在子 shell 中输出变量x的值,结果为 5。
- (echo $$; echo $x; ps; x=5; echo $x):这是一个在子 shell 中执行的命令组。
- 进程列表
- ps:这行命令显示当前系统中的进程列表,包括 PID、TTY、TIME 和 CMD 等信息。
- 父进程和子进程的变量关系
- echo $x:在父进程中再次输出变量x的值,结果为 10。这表明在子 shell 中对x的赋值不会影响父进程中的x。
- x=5; echo $x:在父进程中重新将x赋值为 5 并输出,结果为 5。
- 进入子 shell 并显示进程号
- bash:这行命令进入一个新的 bash 子 shell。
- echo $$:在新的子 shell 中显示子 shell 的进程号,结果为 3364。
- ps:在新的子 shell 中显示当前系统中的进程列表。
- 在子 shell 中操作变量
- echo $x:在新的子 shell 中输出变量x的值,结果为 5。这表明在父进程中对x的赋值会被子 shell 继承。
- x=2; echo $x:在新的子 shell 中将x赋值为 2 并输出,结果为 2。
- 退出子 shell
- exit:这行命令用于退出当前的子 shell,返回到父 shell。
- 再次输出变量和进程号
- echo $$:在父进程中再次显示进程号,结果为 3080。
- echo $x:在父进程中再次输出变量x的值,结果为 10。
总结:
- 这组命令演示了在 Linux shell 中如何操作变量,如何进入和退出子 shell,以及子 shell 和父进程之间变量的继承和独立性。
- 在子 shell 中对变量的赋值不会影响父进程中的变量,而在父进程中对变量的赋值会被子 shell 继承。
总结:
一、Subshell(子 shell)
- 定义
- 子 shell 是由当前 shell(父 shell)派生出来的一个独立的 shell 环境。它通常通过使用括号()来创建。
特性
- 环境变量隔离:
-
- 子 shell 有自己独立的环境变量空间。在子 shell 中修改的变量不会影响到父 shell 中的同名变量,反之亦然。
-
- 进程关系:
-
- 子 shell 是父 shell 的一个子进程。父 shell 在创建子 shell 时会进行进程分叉(fork)操作。
-
二、Child Shell(子 shell 的一种特殊情况)也可以说是 子进程Shell
- 定义
- Child shell 通常是指通过执行bash或sh等 shell 命令而创建的新的 shell 环境。
特性
- 环境变量继承与修改:
-
- 当创建一个 child shell 时,它会继承父 shell 的环境变量。但是,在 child shell 中修改的变量不会影响父 shell 中的同名变量。
-
- 进程关系:
-
- 与 subshell 类似,child shell 也是父 shell 的一个子进程。但是,child shell 是一个全新的 shell 实例,而 subshell 是在当前 shell 环境中创建的一个临时环境。
-