bashshebangsubshell

Why $BASH_SUBSHELL doesn't work with /bin/bash shebang


Doing some tests, I discovered that setting the bash shebang in a script would cancel the $BASH_SUBSHELL behavior.

# in the terminal
$ echo $BASH_SUBSHELL
0
$ (echo $BASH_SUBSHELL)
1

script_no_shebang.sh

echo $BASH_SUBSHELL
$ ./script_no_shebang.sh
0
$ test=$(./script_no_shebang.sh)
$ echo $test
1

script_shebang.sh

#!/bin/bash
echo $BASH_SUBSHELL
$ ./script_shebang.sh
0
$ test=$(./script_shebang.sh)
$ echo $test
0

Any idea if this is a bug or an expected behavior ?

I tried several combinations as tested above. Using a lot of bash functions I don't see myself removing the shebang to use $BASH_SUBSHELL.


Solution

  • When the script starts with a shebang, the operating system kernel executes the shebang as a command, with the script name as its argument. So it's equivalent to running

    /bin/bash ./script_shebang.sh
    

    This starts a new bash process that initializes the subshell level to 0.

    When there's no shebang, the shell executes the script itself in a subshell, so it increments the subshell level.

    You can see the equivalent of the shebang if you do

    test=$(/bin/bash ./script_no_shebang.sh)
    

    Basically, starting a new bash instance is not the same as a subshell.