18

Here is a simple question. Why does this not behave the way I think it would:

(echo "Test 1"; exit) && echo "Test 2"

...or...

VAR1=1
VAR2=2
[ $VAR1 == $VAR2 ] || (echo '$VAR1 does not equal $VAR2, exiting.'; exit)
echo -e 'Well, I\'m still alive yo!'

Running either of those two snippets will result in script execution continuing despite an explicit exit command.

Obviously the parentheses are affecting the command for some reason, my question is why?

4 Answers 4

24

The parentheses execute their contents in a subshell, it is therefore the subshell that exits.

You would usually achieve the same effect either with another && or using {} instead of ().

{ echo "Test 1"; exit; } && echo "Test 2"

Or

echo "Test 1" && exit && echo "Test 2"
Sign up to request clarification or add additional context in comments.

3 Comments

How would one do the above without using said 'subshell'?
With this two examples given by Kevin, you will not use subshells ;)
Since it just cost me 5 minutes: the semicolon before the closing bracket is not optional - if it is missing, you will get a syntax error (presumably because bash thinks the } is an argument to the command before)
6

From http://tldp.org/LDP/abs/html/subshells.html

A command list embedded between parentheses runs as a subshell.

( command1; command2; command3; ... )

A code block between curly brackets does not launch a subshell.

{ command1; command2; command3; . . . commandN; }

In the first case the exit is being run by the sub shell which terminates and returns control to the invoking shell.

Comments

1

The contents of ( ... ) are executed in a subshell, so you just exit this shell. This approach should work better for you and it is easier to read an maintain for the next person to come along and open your script:

VAR1=1
VAR2=2
if [ $VAR1 == $VAR2 ] ; then
    echo -e "Well, I'm still alive yo!"
else
    echo "$VAR1 does not equal $VAR2, exiting."
    exit
fi

Comments

-1

Just remove the parentheses and it should do what you want.

The parentheses are equivalent to putting their content into another shell script, where the exit just exits that shell script.

1 Comment

Removing the parenthesis alone won't work because of the operator's priority. The || will operate only in the first argument next to it. Try BOOL || echo msg ; echo exit, with BOOL=true and BOOL=false.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.