Using parens puts the commands in a subshell which is not always what you want. Alternatively, use curly braces:
command && echo "Ok, continuing" || { echo "Check internet connection"; exit 1; }
The trick here is that, unlike parens, the final command in braces must be followed by ;
.
Why a semicolon or newline is required
A curly brace is a valid argument to a command. For example, here is a curly brace as an argument to echo
:
$ echo }
}
Consequently, if the shell sees:
{ command1; command2 }
The shell interprets command1 as having no arguments and command2 as having one argument consisting of the character }
. A curly brace }
is only interpreted as closing a grouping if it follows a semicolon or newline. To make the above work:
{ command1; command2; }
Subshells and the difference between {...}
and (...)
Observe that the following sets x
to 10 but that that setting is forgotten before the echo
command runs:
$ x=0; false || ( echo Hello; x=10 )
Hello
$ echo $x
0
With curly braces, by contrast, the setting of x=10
is remembered:
$ x=0; false || { echo Hello; x=10; }
Hello
$ echo $x
10
The difference is because variable assignments in a subshell do not survive after the subshell completes.
Documentation
From man bash
:
(list)
list is executed in a subshell environment (see COMMAND EXECUTION
ENVIRONMENT below). Variable assignments and builtin commands that
affect the shell's environment do not remain in effect
after the command completes. The return status is the exit status of
list.
{ list; }
list is simply executed in the current shell environment. list must
be terminated with a newline or semicolon. This is known as a group
command. The return status is the exit status of list. Note that
unlike the metacharacters ( and ), { and } are reserved words and
must occur where a reserved word is permitted to be recognized.
Since they do not cause a word break, they must be separated from list
by whitespace or another shell metacharacter.
[Emphasis added]
()
and{}
.