Child Process

Subshell () vs Pipeline | vs Script ./script.sh

Subshell () (More at Parenthesis Spawn a Subshell: $() AND ())

  • Fork-only: creates a copy of the current shell
  • Inherits everything: all variables, functions, aliases (exported or not)
  • Example: (echo $myvar; myfunc) works even if nothing is exported

Pipeline |

  • Each command in a pipeline runs in a subshell (fork-only)
  • Inherits everything like () subshells
  • Warning: In some shells, the last command ALSO runs in a subshell
  • Example: echo "test" | myfunc | somefunc works even if myfunc isn't exported

Script ./script.sh

  • Fork+exec: creates a new, fresh shell process
  • Inherits only exported:
    • exported environment variables
    • exported functions (export -f)
      • bash-specific, not POSIX. Many shells don't support exporting functions at all.
  • Example: ./script.sh can't see myvar or myfunc unless exported

Key difference: Subshells and pipeline commands are copies of the parent shell with full state. Scripts are new shells that start clean with only exported environment.

Common gotcha: All three create child processes, so variable changes don't affect the parent:

(myvar=1)                    # parent doesn't see this
echo "test" | read myvar     # parent doesn't see this
./script.sh                  # sets myvar=1 inside, parent doesn't see it

Children
  1. Parenthesis Spawn a Subshell: $() AND ()