On piping in shell scripts and var scoping
Memento:
When writing shell scripts keep an eye on subshell creation to avoid unexpected results.
Today I was doing something along these lines:
#!/bin/sh TOT=0 seq 1 3 | \ while read n; do TOT=$(expr -- $TOT + $n) echo $TOT done echo $TOT
Which led to this output:
1
3
6
0
Definitely not what I would have expected.
Fortunately the web came to the rescue, see this detailed explanation of what's going on here. It turned out that piping a command into a while loop makes bash to fork a subshell, so the variable values are not preserved when the subshell completes its execution.
You can workaround the issue by putting the output of the command into a HEREDOC string and redirecting that into the loop:
#!/bin/sh TOT=0 while read n; do TOT=$(expr -- $TOT + $n) echo $TOT done <<EOF $(seq 1 3) EOF echo $TOT
Which gives:
1
3
6
6
Comments
Thanks alot! I've been
Thanks alot! I've been looking for such an elegant solution for a long time!
Post new comment