Shell tips and tricks
VirginSnow at vfemail.net
VirginSnow at vfemail.net
Thu Nov 1 12:25:27 EDT 2007
> Date: Wed, 31 Oct 2007 13:35:07 -0400 (EDT)
> From: "Steven W. Orr" <steveo at syslang.net>
> On Wednesday, Oct 31st 2007 at 13:13 -0000, quoth Paul Lussier:
> foo=44
> p1 | while read line
> do
> dosomething
> foo=$((foo + 1))
> done
> echo "foo = $foo"
>
> Given (let's say) 5 lines of output from p1, what will it print?
Note that the following will do "what you'd expect":
foo=44
while read line; do
foo=$((foo + 1))
done < <(p1)
echo "foo = $foo"
The difference is that this (this whole example) is run in the same
subshell. When you use "|", the "while...do...done" runs in a
different subshell... which disappears by the time bash gets around to
running 'echo $foo".
One trick which I've used to get around this is:
foo=44
p1 | while read line
do
dosomething > /dev/null 2>&1 # redirect output somewhere safe
foo=$((foo + 1))
echo MAGIC "$foo" #use magic just in case unexpected output reaches stdout
done | grep ^MAGIC | tail -n 1 | {
read magic foo
echo "foo = $foo"
# the rest of the code which needs access to foo
}
More information about the gnhlug-discuss
mailing list