Groups & Sub-Shells
There are two ways to group a list of commands to be executed as a unit. When commands are grouped, redirections may be applied to the entire command list. For example, the output of all the commands in the list may be redirected to a single stream. Or you may run the entire command list as a single command in an outer pipeline.
The exit status of grouped commands is the exit code of the last command within the list.
Groups
The format is :
{
command1
command2
...
}
Placing a list of commands within curly braces allow you to group those commands into a single unit. Commands can be anything. from simple command to buitlin commands, loops, functions and anything else.
Unless explicitly redirected, redirections applied on the group are applied on all the commands within the list . for example:
{
command1
command2
command3 < file.txt > file2.txt
} <file3.txt >file4.txt
The commands command1
and command2
will read from file file3.txt
and write to file4.txt
. While command3
will read from file.txt
and write to file2.tx
. This is because the command3
has explicit redirections. While other commands inherit the redirections from the group.
Because the command group is a single unit, you can treat it just like a simple command. For example you can use it within pipelines:
{ echo foo; echo bar; } | cat
TIP
Do not be confused by the semicolon in the above example, semicolons ;
is just one the tokens that you can use to separate commands. just like a new line \n
. learn more about possible separators in their dedicated section.
WARNING
The closing brace must be preceeded by a separator (;
, \n
...) to be recognized as end of group. For example this is not valid: { command }
.
Sub-Shells
The second way of grouping commands is by wrapping commands within parentheses (...)
. like this:
(
command1
command2
...
)
Grouping commands this way is called a sub-shell
. It has the same posibilities as the {...}
groups. Except one difference. Commands that run in a sub-shell are executed in a separate context. This means that all variables mutated or declared within the sub-shell do not affect the global scope.
For example:
var=foo
(
var2=bar
var3=baz
)
echo var:$var var2:$var2 var3:$var3
Will output:
echo var:foo var2: var3:
TIP
Unlike groups, sub-shells do not require any separator before the closing parenthese.