patternbashModerate
Subshell vs command group: ( ) vs { } for scoping
Viewed 0 times
subshellcommand groupscopingisolationforkvariable scopecd isolation
Problem
Developers are unsure when to use ( ) (subshell) vs { } (command group) for grouping commands. Choosing the wrong one either creates unnecessary overhead or leaks variable/directory changes.
Solution
( commands ) — runs in a forked subshell. Changes to variables, working directory, and traps are isolated.
{ commands; } — runs in the current shell. No fork, but changes DO propagate.
# Subshell: cd is isolated
( cd /tmp && ls )
echo "Still in $PWD" # original directory
# Command group: no subshell overhead, but no isolation
{ cd /tmp && ls; }
echo "Now in $PWD" # /tmp — changed!
# Use subshell for isolated env changes:
(export VAR=test; external_script)
# Use command group for efficient redirection of multiple commands:
{ echo header; cat data; echo footer; } > output.txt
{ commands; } — runs in the current shell. No fork, but changes DO propagate.
# Subshell: cd is isolated
( cd /tmp && ls )
echo "Still in $PWD" # original directory
# Command group: no subshell overhead, but no isolation
{ cd /tmp && ls; }
echo "Now in $PWD" # /tmp — changed!
# Use subshell for isolated env changes:
(export VAR=test; external_script)
# Use command group for efficient redirection of multiple commands:
{ echo header; cat data; echo footer; } > output.txt
Why
A subshell forks a new process; it is isolated but costs a fork+exec. A command group is just syntactic grouping with no new process. Use subshells when isolation matters, groups when performance matters.
Gotchas
- { } requires a semicolon or newline before the closing brace and a space after the opening brace
- Pipes create implicit subshells: 'cmd | while read line; do var=$line; done' — var is lost after pipe
- Use lastpipe option ('shopt -s lastpipe') to run the last pipe segment in the current shell
- Subshells in pipelines prevent variable export back to parent — use temp files or process substitution
Code Snippets
Subshell vs command group examples
# Subshell: isolated
(
cd /tmp
VAR="inside"
echo "In: $PWD"
)
echo "Out: $PWD" # original dir
echo "${VAR:-unset}" # unset
# Command group: same shell
{
echo "line 1"
echo "line 2"
echo "line 3"
} > /tmp/output.txt # all three redirected at once
# Pipe subshell gotcha
count=0
echo "a b c" | while read word; do
(( count++ )) || true
done
echo $count # 0! — count modified in subshellContext
Grouping commands, isolating directory changes, or redirecting multiple commands
Revisions (0)
No revisions yet.