Two ways to group commands
{ cmd1; cmd2; }— run in current shell. Variables persist after the group.(cmd1; cmd2)— run in a subshell. Variable changes don't leak out. Slightly slower (fork).
When to use {}
Apply a single redirection to several commands:
{
echo "=== build log ==="
date
./build.sh
} > build.log 2>&1The whole block writes to build.log. Saves three >> redirections.
When to use ()
Isolate side effects. Common: cd into a dir, do work, come back automatically:
(
cd ~/projects/temp
./make.sh
)
# We're still in the original directoryVariables, cd, set options inside the parens don't affect the parent shell.
Capturing in $()
$(cmd) is also a subshell. That's why x=10; $(x=20) doesn't change x — the assignment lived in a fork.
Watch the syntax for {}
- Need spaces inside the braces.
- Need a trailing semicolon (or newline) before the closing brace.
{cmd} doesn't work; { cmd; } does. The shell's parser is picky here.
Isolation is not atomicity
A subshell keeps directory and variable changes from leaking back, but it does not automatically stop after an inner failure. Design the failure flow explicitly.
The final command controls the group's status
An earlier failure followed by a successful echo can make the whole group look successful. Return failures deliberately when the group is used as a gate.