I am learning shell scripts and stuck at this little experimental shell scripts:
1 #!/usr/bin/env bash
2 A=1
3 (A=2;echo "A is $A in $SHLVL")
4 echo "A is $A in $SHLVL"
5 exit 0Without doubt, $A in line 3 and line 4 are different from each other, which can be explained that it is because the parent process cannot read variables created in the child process, that is, the subshell. However, the $SHLVL in line 3 and line 4 are the SAME, which I thought that $A in line 3 should have been bigger than $A in line 4 by 1. Didn't commands in line 3 executed in subshell? I don't know where I misinterpreted.
Thanks for your help.
2 Answers
Your shell level isn't changing in the script you have made. When you echo $SHLVL in your terminal you will see the shell's current run level. If you use the command bash in your terminal, you will have created a subshell and increased the shell level until you exit that subshell. The subshell you create in your script is a child of a parent running in the shell level OF the parent. That is why $SHLVL is the same in the parent and child processes.
In the Advanced Bash-Scripting Guide I found this:
While the
$BASH_SUBSHELLinternal variable indicates the nesting level of a subshell, the$SHLVLvariable shows no change within a subshell.
Seems right, it fits your results. On the other hand Bash Reference Manual says:
SHLVLIncremented by one each time a new instance of Bash is started. This is intended to be a count of how deeply your Bash shells are nested.
I admit this may be misleading. I think "a new instance of Bash is started" when you explicitly invoke bash. According to this interpretation subshells like (…) do not count; they are treated as parts of the original shell.