problems with 'while read'
Nicole Delbecque & Paul Bijnens
FFAAC09 at cc1.kuleuven.ac.be
Tue May 7 08:51:18 AEST 1991
In article <3635 at dagobert.informatik.uni-kiel.dbp.de>,
wib at informatik.uni-kiel.dbp.de (Willi Burmeister) says:
>
>Just a simple (??) question: Why does this small program not work?
>
>------ cut here ------ cut here ------ cut here ------ cut here ------
>#!/bin/sh
>
>cat << EOF > hugo
>one
>two
>three
>four
>EOF
>
>while read num
>do
> echo "do something with <$num>"
> last=$num
>done < hugo
>
>echo "last num = <$last>"
>------ cut here ------ cut here ------ cut here ------ cut here ------
>
>the output will always be:
>
>do something with <one>
>do something with <two>
>do something with <three>
>do something with <four>
>last num = <>
>
>
>What I want is:
>
>do something with <one>
>do something with <two>
>do something with <three>
>do something with <four>
>last num = <four>
> ^^^^
You are using the Bourne shell. This shell implements the redirection
of the while-loop with a subshell. And as you probably already
know: you cannot get the variable from the subshell to the parent shell.
(Read also the FAQ about this problem.)
I have been told the Korn shell does this right...
One way round this, using an ugly temporary file:
trap "rm -f /tmp/sh$$; exit" 0 1 2 3 15
while read num
do
echo "Do something with $num"
echo $num > /tmp/sh$$
done << EOF
one
two
three
EOF
read last < /tmp/sh$$
echo last is $last
A better way is to do some manipulation with the filedescriptors.
We can avoid the redirection of the loop like this:
cat > hugo << EOF
one
two
three
EOF
exec 3<&0 0<hugo # duplicate the standard input filedescriptor
# and redirect it then to read from the file
while read num # standard input now reads from file "hugo"
do
echo "Doing $num"
last=$num
done
exec 0<&3- # restore standard input from 3, and close fd 3
echo last is $last
et voila, it works. (At least, it works with me.)
--
Polleke (Paul Bijnens)
Linguistics dept., K. University Leuven, Belgium
FFAAC09 at cc1.kuleuven.ac.be
More information about the Comp.unix.shell
mailing list