Environment Variables, Exports, and Subshell Boundaries
Shell variables and process environments overlap, but they are not the same. Export, fork/exec inheritance, subshells, pipelines, and sourcing define where changes survive.
A shell stores variables for its own evaluation, while every process receives a separate environment: a collection of name-value strings copied from its parent. Confusing those two layers produces many “the variable disappeared” bugs.
Assignment is local until export
project=demo
sh -c 'printf "%s\n" "$project"' # empty
export project
sh -c 'printf "%s\n" "$project"' # demo
The first assignment creates a shell variable. export marks the name for inclusion in environments created for future commands. It does not create a shared global variable; the child gets a copy and cannot modify the parent’s value.
A temporary assignment applies only to one command’s environment:
LC_ALL=C sort names.txt
This is often safer than changing the interactive shell’s locale for everything that follows.
A subshell cannot send assignments back
Parentheses explicitly create a subshell environment in POSIX shells:
where=$PWD
(cd /tmp; where=$PWD; printf '%s\n' "$where")
printf '%s\n' "$where"
The directory and variable changes inside parentheses disappear when that environment ends. Command substitutions also execute in a subshell environment. Pipeline components commonly do as well, though extension behavior differs among shells; never rely on a variable assigned inside a pipeline being available afterward in portable code.
Sourcing is intentionally different
. ./settings.sh
The dot command, also spelled source in some shells, evaluates a file in the current shell. Its assignments, functions, cd, and options can therefore persist. That power is why a sourced file must be trusted and should avoid calling exit unexpectedly.
Inspect the right layer
set displays shell state and often much more; export -p shows exported names; env prints the environment passed to an external program. /proc/PID/environ on Linux is a process snapshot, not proof of the current contents of another shell’s unexported variables.
Secrets deserve special care. Environment variables may be visible to same-user process inspection, crash reporting, or diagnostic tools, and they propagate automatically to descendants. Use scoped assignments or secret-specific file descriptors where the application supports them, then unset values that no longer need to remain in the shell.
Sources: