Subshells
Bash · Reference cheat sheet
Subshells
Bash · Reference cheat sheet
📋 Overview
A subshell is a child shell process. Changes to variables, cd, and shell options inside it do not affect the parent. Subshells appear with (…), pipelines, command substitution $(…), and process substitution contexts.
🔧 Core concepts
| Construct | Subshell? |
|---|---|
( cd /tmp && pwd ) | Yes |
\{ cd /tmp && pwd; \} | No (group command; needs trailing ;) |
$(cmd) / `cmd` | Yes |
cmd | cmd | Each side may be (bash: last may not with lastpipe) |
coproc | Separate process |
Background cmd & | Child process |
Use subshells to isolate cd, temporary umask, or option changes. Use \{ …; \} when you need side effects in the current shell.
💡 Examples
Isolate directory change:
pwd
( cd /tmp && ls )
pwd # unchangedGroup vs subshell:
{ echo a; echo b; } > both.txt # current shell
( echo a; echo b ) > both.txt # subshell (usually fine for I/O)Capture without polluting:
version="$(
cd "$repo" || exit 1
git describe --tags
)"Avoid pipeline subshell for vars:
# bad: count lost
# printf '%s\n' a b | while read -r x; do ((count++)); done
count=0
while read -r x; do ((count++)) || true; done < <(printf '%s\n' a b)
echo "$count" # 2⚠️ Pitfalls
- Variable assignments in pipelines often don’t persist—use process substitution or lastpipe.
(exit 1)only exits the subshell; parent continues unless you check status.- Nested subshells add process overhead; don’t overuse in tight loops.
cdin scripts: prefer subshell orpushd/popdover relying on latercd -.- Functions defined in a subshell vanish when it ends.
exportinside subshell does not affect parent environment.