In a comment on another post, @JonathanLeffler stated that:
{ ... } | somecommand is run in a sub-shell and doesn\'t affect the parent shell. Demo:
Each side of a pipeline becomes a subshell at least.
X=PQR; echo $X; { X=ABC; echo $X; } | cat; echo $X
will make a subshell/process of , atleast { X=ABC; echo $X; } and cat.
"Each command in a pipeline is executed as a separate process (i.e., in a subshell)." , from man bash
If you instead do this
X=PQR; echo $X; { X=ABC; echo $X; } ; echo | cat; echo $X
You'll see afterwards that echo $X shows ABC.
There's other ways that commands are executed in subshells too, e.g. if you background a subcommand: { X=SUB ; sleep 1; } & , that group will run in a subshell, whereas just { X=SUB ; sleep 1; } will not.
If you want to group commands that always execute in a subshell, use parenthesis, (X=ABC ; echo $X) instead of braces.