What Is a Subshell? A Child Shell for Isolation
A subshell is a child shell process that runs a group of commands in its own copy of the environment, so changes inside it do not affect the parent.
Sometimes the shell spawns a child copy of itself, a subshell, to run a group of commands in isolation. Variable changes and directory changes inside a subshell vanish when it ends. This is useful for scoping, but it is also a classic source of confusion when a variable mysteriously does not stick.
What a subshell is
A subshell is a separate shell process forked from the current one. It inherits the parent's environment, but any changes it makes, like setting a variable or changing directory, stay local to it.
How subshells are created
- Parentheses:
( cd build && make )runs in a subshell. - A pipeline: each side of a
|may run in its own subshell. - Command substitution:
$(...)runs its command in a subshell.
The isolation effect
Because a subshell has its own copy of the environment, ( cd /tmp ) does not change the parent's directory after it returns. This isolation is the point, but it surprises people who expect changes to persist.
A common pitfall
A variable set inside a piped loop may not survive, because the loop ran in a subshell. find . | while read f; do count=$((count+1)); done can leave count unchanged in the parent.
Subshells in CI
In CI scripts, subshells help group commands without polluting the outer shell, like running a build in a subdirectory. But if you rely on a variable set inside a subshell later, it will be empty, which causes hard-to-spot bugs.
Predictable scripts on managed runners
On Latchkey runners, using a subshell to scope a directory change keeps the rest of your step clean. Just remember that values you need afterward must be captured into the parent shell, not set inside the subshell.
Key takeaways
- A subshell is a child shell running commands in an isolated environment copy.
- Changes inside a subshell, like cd or variables, do not persist to the parent.
- Parentheses, pipelines, and
$(...)all create subshells in scripts.