There are 5 types of scopes in Bash:
- Environment Scope -
export x=1; echo "$x"; command
- Shell Scope -
x=1; echo "$x"
- Function Scope -
f () { local x=1; echo "$x"; }; f
- Command Scope -
x=1 command
- Subshell Scope -
x=1; (echo "$x"; y=2); echo $y
There is no block scoping for command groups, i.e. { local x=1; }
does not work.
For the purposes of scoping, comand groups over no isolation. Everything is as if
done in the main shell scope.
The environment scope makes variables available in:
- the current shell,
- immediate subprocesses,
- and subshells
The shell scope makes variables available in:
- the current shell,
- and subshells
The function scope makes variables available in:
- the current shell function
The command scope makes variables available in:
- the immediate command subprocess and nothing else
The subshell scope is the equivalent of a new shell, and has all the features of a shell scope, and its own environment scope. The key feature is that variables declared here will not leak into the parent shell.
If you export a variable inside a function, whether local or not, it will be equivalent to a variable in the main shell's environment scope.
Because there's no block scoping, neither for
nor while
creates a block
scope either. However if you pipe into a while
command, you'll create a
subshell scope. This is not true for ZSH however.
Both command substitution $()
and process substitution <()
creates a
subshell scope. Note that ZSH has =()
while probably creates a subshell scope
too.