Let's see what the Bash manual says (3.7.3 Command Execution Environment)
The shell has an execution environment, which consists of the
following:
- shell parameters that are set by variable assignment or with set or inherited from the shell’s parent in the environment
- shell functions defined during execution or inherited from the shell’s parent in the environment
Command substitution, commands grouped with parentheses, and
asynchronous commands are invoked in a subshell environment that is
a duplicate of the shell environment [...]
Changes made to the subshell environment cannot affect the shell’s execution environment.
In 3.2.2 Pipelines, it's also said
Each command in a pipeline is executed in its own subshell
(Of course that only applies to multi-command pipelines)
So, the parts of a pipeline, as well as other subshells, get copies of all the shell variables, but any changes to them are not visible to the outside shell.
With other commands, you still need to export:
When a simple command other than a builtin or shell function is to be
executed, it is invoked in a separate execution environment that
consists of the following.
- shell variables and functions marked for export, along with variables exported for the command, passed in the environment
Food for thought: what does this print?
bash -c 'f() { echo "$a $b"; }; a=1; b=1; (b=2; f); f'
whilestructures, which is what that other Q is really aboutexportcommand.whileloop gets a copy of the local (non-exported)varvariable, which is defined before the pipeline. Similar thing would happen if the left hand side of the pipe was something likeif true; then echo "$var"; var=quick; echo "The $var brown fox"; fi.