Skip to content
Latchkey

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.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →