Grouping Constructs

There are two grouping constructs, called brace groups and subshells, which can group lists of commands together.

Subshell

A subshell executes a compound-list, enclosed by the ( and ) operators, in a subshell environment; variable assignments and other builtin commands that affect the environment do not affect the outer shell environment after the list finishes. It takes the form,

subshell:
(
compound-list
)

Here is an example of how commands executed in a subshell do not affect the current execution environment,

$ message="Hello World!"
$ echo "$message"
Hello World!
$ ( message="Goodbye World!"; echo "$message"; )
Goodbye World!
$ echo "$message"
Hello World!

Exit Status

The exit status of a subshell is the exit status of the last command executed in the enclosed compound-list.

Brace Group

A brace group executes a compound-list, enclosed by the { and } reserved words, in the current execution environment. It takes the form,

brace-group:
{
  compound-list
}

Here is an example of how commands executed in a brace group affect the current execution environment,

$ message="Hello World!"
$ echo "$message"
Hello World!
$ { message="Goodbye World!"; echo "$message"; }
Goodbye World!
$ echo "$message"
Goodbye World!

Exit Status

The exit status of a brace group is the exit status of the last command executed in the enclosed compound-list.

Warning

Keep in mind that { and } are reserved words, while ( and ) are operators. This is a historical artefact with an important effect:

The last command in a subshell’s command list can be terminated with the ) operator. However, the last command in a brace group’s command list must be explicitly terminated with a control operator (such as ;) or a newline before the closing brace (}). This is because reserved words are only recognized if they appear in specific locations–e.g. as the first word of a command.

For example,

{ echo test }   # '}' is interpreted as an argument to `echo', not a closing brace
}               # This is interpreted as the closing brace

# Output: "test }"

( echo test )   # ')' is a recognized operator

# Output: "test"