Hello. Here's a quick summary of what happens when run by a subshell:
If you make it a command group (that is, enclose it in brace "{}"), it will be treated as a single execution unit, and it will be executed in the original shell as it is [^ 3]. There are also functions and while do ~ done [^ 4] to handle similar chunks.
The combination of pipelines and command groups was easy to misunderstand. If you read the example below,
command1; command2; { command3; command4; } | { commmand5; command6; }; command7; command8
command1, command2command7, command8command3, command4command5, command6Next, considering the variable update in the subshell, this does not propagate to the original shell. In the example below, the output of echo $ n at the end will be empty.
$ unset n; { n=0; printf 'a\nb\n'; } | cat; echo $n
a
b
$ unset n; printf 'a\nb\n' | (n=0; while read -r line; do n=$((n+1)); done; echo $n); echo $n
2
$ unset n; printf 'a\nb\n' | { n=0; while read -r line; do n=$((n+1)); done; echo $n; }; echo $n
2
$
If you update variables in the original shell, you can avoid "update variables in subshells". The example below is crowded, but `` n = 0``` is executed in the original shell and the output of the trailing ```echo $ n``` is ``` 0```.
$ unset n; { n=0; printf 'a\nb\n' | cat; } ; echo $n
a
b
0
$
Similarly, you can use a "here document" to update variables in the original shell (you can avoid the pipeline). In the example below, the output of echo $ n at the end will be `` `2```.
$ unset n; { n=0; while read -r line; do n=$((n+1)); done << EOT
$(printf 'a\nb\n')
EOT
echo $n; }; echo $n
2
2
$
Alternatively, you can use Process Substitution in Bash etc. instead of POSIX shell:
$ unset n; { n=0; while read -r line; do n=$((n+1)); done < <(printf 'a\nb\n'); echo $n; }; echo $n
2
2
$
[^ 1]: The format of $ (...)` `` to get the standard output of the subshell execution enclosed in parentheses" () "is similar. However, the form $ ((...))` `` is executed in the original shell ("Variables in subshell").
[^ 2]: Refers to an execution example such as executing a shell script or `sh -c'n = 0; echo $ n' `. On the other hand, if you run it with the source command, it will be executed in the original shell.
[^ 3]: This is similar to enclosing in parentheses "()", but it is not treated as a subshell.
[^ 4]: For example, `` `printf'a \ nb \ n'| while read -r line; do echo $ line; done```.
Recommended Posts