我对这两个变量有点困惑。
尽管$BASH_SUBSHELL内部变量表示子shell的嵌套级别,$SHLVL变量在子shell中不发生变化。
这到底是什么意思?如果我在另一个shell中打开一个shell,$SHLVL的值会增加。那不就是一个子shell吗?
尽管$BASH_SUBSHELL内部变量表示子shell的嵌套级别,$SHLVL变量在子shell中不发生变化。
这到底是什么意思?如果我在另一个shell中打开一个shell,$SHLVL的值会增加。那不就是一个子shell吗?
/bin/sh
或/bin/bash
等)在此上下文中不是子shell。$(command)
)是子shell(旧版反引号调用也是如此)。echo '5.1+5.3' | bc -l
)为管道的每个组件创建子shell。<(command)
)会创建一个子shell。
分组命令(例如(declare a=5; echo $a)
)会创建一个子shell。
在后台运行命令(例如sleep 1 &
)会创建一个子shell。
可能还有其他情况,但这些是常见的情况。
测试很容易:
$ printf "Outside: $BASH_SUBSHELL , $SHLVL\nInside: $(echo $BASH_SUBSHELL , $SHLVL)\n"
Outside: 0 , 1
Inside: 1 , 1
$ (printf "Outside: $BASH_SUBSHELL , $SHLVL\nInside: $(echo $BASH_SUBSHELL , $SHLVL)\n")
Outside: 1 , 1
Inside: 2 , 1
$ bash -c 'printf "Outside: $BASH_SUBSHELL , $SHLVL\nInside: $(echo $BASH_SUBSHELL , $SHLVL)\n"'
Outside: 0 , 2
Inside: 1 , 2
$ bash -c '(printf "Outside: $BASH_SUBSHELL , $SHLVL\nInside: $(echo $BASH_SUBSHELL , $SHLVL)\n")'
Outside: 1 , 2
Inside: 2 , 2
你的引用来源(通常较差且应尽量避免的ABS)甚至在某种程度上证明了这一点(以及那个“高级”指南中普遍缺乏严谨和质量的另一个例子,表述也相当不清楚):
echo " \$BASH_SUBSHELL outside subshell = $BASH_SUBSHELL" # 0 ( echo " \$BASH_SUBSHELL inside subshell = $BASH_SUBSHELL" ) # 1 ( ( echo " \$BASH_SUBSHELL inside nested subshell = $BASH_SUBSHELL" ) ) # 2 # ^ ^ *** nested *** ^ ^ echo echo " \$SHLVL outside subshell = $SHLVL" # 3 ( echo " \$SHLVL inside subshell = $SHLVL" ) # 3 (No change!)
$SHLVL:
Shell级别,Bash嵌套的深度。如果在命令行中$SHLVL为1,则在脚本中它将增加到2。此变量不受子shell的影响。
$BASH_SUBSHELL:
指示子shell级别的变量。
以下是它们具有不同值的方式:
# In the login bash shell
echo $BASH_SUBSHELL:$SHLVL
0:1
# 1st nested child
bash
echo $BASH_SUBSHELL:$SHLVL
0:2
# 2nd nested child
bash
echo $BASH_SUBSHELL:$SHLVL
0:3
# back to 1st nested child
exit
echo $BASH_SUBSHELL:$SHLVL
0:2
# back to parent shell
exit
echo $BASH_SUBSHELL:$SHLVL
0:1
# first level sub-shell
(echo $BASH_SUBSHELL:$SHLVL)
1:1
# 2nd level sub-shell
( (echo $BASH_SUBSHELL:$SHLVL) )
2:1
# 3rd level sub-shell
( ( (echo $BASH_SUBSHELL:$SHLVL) ) )
3:1