← Back to Bash Course | Chapter 11: Process Management | Lesson 8 of 12

Subshells vs the Current Shell ( ( ) vs { } )

Parentheses run a block of commands in a separate copy of the shell, while curly braces run them directly in the current shell, and that difference decides whether variable changes stick around afterward.

Variable Changes Inside a Subshell Don't Escape

Because ( ... ) forks a separate copy of the shell, any variable assignments made inside it are lost once the subshell finishes; the parent shell's variables are untouched.

Example: Variable Changes Inside a Subshell Don't Escape

bash
#!/bin/bash
count=1
( count=99; echo "inside subshell: $count" )
echo "outside subshell: $count"

Curly Braces Share the Current Shell

{ commands; } groups commands but runs them in the current shell environment, so variable assignments and cd calls inside persist after the block finishes.

Note: Note the required space after { and the semicolon before } — these are syntax requirements, not style choices.

Example: Curly Braces Share the Current Shell

bash
#!/bin/bash
count=1
{ count=99; echo "inside group: $count"; }
echo "outside group: $count"

Isolating a Directory Change

A subshell is a clean way to temporarily cd somewhere and run a command there without having to remember to cd back afterward; once the subshell exits, the parent's working directory is unaffected.

Example: Isolating a Directory Change

bash
#!/bin/bash
mkdir -p sub_demo
echo "before: $(pwd | xargs basename)"
( cd sub_demo && echo "inside subshell: $(pwd | xargs basename)" )
echo "after: $(pwd | xargs basename)"
rmdir sub_demo

exit Behaves Differently in Each

Calling exit inside ( ... ) only terminates that subshell, letting the parent script continue; calling exit inside { ...; } terminates the entire script since it runs in the same process.

Example: exit Behaves Differently in Each

bash
#!/bin/bash
( echo "in subshell before exit"; exit 1; echo "never printed" )
echo "script continues after the subshell exited, status was $?"
Common Mistakes
  1. Assuming ( ... ) and { ...; } are just stylistic alternatives; they have fundamentally different scoping behavior.
  2. Forgetting that { ...; } requires a space after {, a semicolon (or newline) before }, while ( ... ) needs neither.
  3. Using a subshell for something that must affect the calling script's state, like cd or exporting a variable, and being confused when the change disappears.
Chapter Summary
  • ( commands ) runs in a subshell: a forked copy of the shell with its own variables, working directory, and traps.
  • { commands; } runs in the current shell: variable changes, cd, and exit all affect the calling shell directly.
  • A subshell is useful for isolating side effects, such as temporarily changing directory without affecting the rest of the script.
  • exit inside ( ... ) only ends the subshell, not the whole script; exit inside { ...; } ends the entire script.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.