Bash – Why Parentheses Return Exit Status but Not Braces

bashshell-script

I understand that parentheses cause the commands to be run in a subshell and braces cause the commands to be grouped together but not in a subshell.

When I run this with parentheses:

no_func || (
    echo "there is nothing"
    exit 1
)

echo $?

This returns the exit status:

/Users/myname/bin/ex5: line 34: n_func: command not found
there is nothing
1

But when I use braces:

no_func || {
    echo "there is nothing"
    exit 1
}

echo $?

This doesn't return the exit status.

/Users/myname/bin/ex5: line 34: no_func: command not found
there is nothing

But why one returns the exit status and another doesn't?

Best Answer

Look at the command execution trace (set -x). With braces:

+ no_func
./a: line 3: no_func: command not found
+ echo 'there is nothing'
there is nothing
+ exit 1

exit exits the (sub)shell. Since braces don't create a subshell, exit exits the main shell process, so it never reaches the point where it would run echo $?.

Related Question