Subshell
Subshell#
Subshell 的定义在一些书本或资料中模糊不清,给出的解释往往和某些例子自相矛盾,让人捉摸不透。
因此,为了避免这种语义与逻辑上的问题,这里不会给出它的定义(建议参考官方 BASH 手册),
也不会使用 “子 Shell” 这个翻译,仅仅从它的实际表现去理解它的定义。
下面列举的变量和 Subshell 概念有着密切的联系。
BASH_SUBSHELL#
Shell 变量,非环境变量,官方手册解释。
也可以使用 man 命令,内容可能会有一点差别。
SHLVL#
环境变量,官方手册解释。
使用 man 命令。
这个值是从 1 开始的。
命令分组#
全称 Command Grouping,Bash 提供两种方法创建命令分组。
括号:()#
该方法会创建一个 Subshell 环境去处理命令分组。
可以得出以下结论。
- BASH_SUBSHELL:每创建一个 Subshell 就加 1。
- SHLVL:无论创建多少个 Subshell,都不变。
花括号:{}#
这种方法不会创建 Subshell,命令分组是在当前 Shell 的上下文中处理的。
在语法上,花括号与命令之间的空格不能省略,每个命令结尾的分号也是必须的。
Shell PID#
可通过 BASHPID 或 $$
查看 Shell 的 PID,但它们是有区别的。
BASHPID#
Shell 变量,非环境变量,官方解释。
使用 ()
查看 BASHPID。
可以看到,BASHPID 输出了 Subshell 的 PID。
特殊参数 $$#
官方解释。
在 Subshell 中,$$
表示的是 invoking shell 的 PID。
可以看到,无论有多少个 Subshells,$$
始终表示顶层 Bash 的 PID。
创建 Bash 实例#
在 Bash 中输入 bash
就可以创建一个全新的 Bash 实例。
这时候再观察一下上面提到的变量。
- BASH_SUBSHELL:没有变化。
- SHLVL:从 1 -> 2。
- BASHPID:新 Bash 实例的 PID。
- $$:新 Bash 实例的 PID。
如果说这种创建 Bash 的方式也是 Subshell 的话,语义和表现上就会自相矛盾。