Curly brackets { }
don't create subshells, round brackets do:
BASH(1)
(list)
list is executed in a subshell environment.
{ list; }
list is simply executed in the current shell
environment.
So, neither the if
statement nor the ... || { }
form have the potential to create a subshell.
A subshell environment may be created if round brackets ( )
are used instead of curly brackets. The OR operator ||
would only allow this stage to be reached if the first command returned a non-zero status (ie. ./create-git-tag.sh failed).
If set -e
is used, all forms exhibit the same behaviour (upon the test command failing the shell exits immediately) – but behind the scenes the round brackets will have created a subshell (which doesn't appear to be useful in this example).
If set -e
wasn't used, creating a subshell with ( )
would mean that the subshell would exit, but the calling shell would continue – commands which follow would still be executed.
In all cases the echo-exit command chain (and associated subshell for round brackets) is only entered upon the test command failing. But the purpose of making conditional logic is that something might fail or it might not – this is where your wording in the question doesn't make sense:
I am guessing that the if block does not create a subshell and therefore would exit before the if block was entered?
The if block is "entered", it runs the test command to determine what to do next.
Personally I find the if
statement clearer to read and prefer to use that in scripts. Operators &&
and ||
I might use in if
's place when I'm using the shell "interactively".
if
block exit before it was entered? That makes no sense.if (thisCallThrowsAnError()){}
then the block would never get entered..right..duh