[Gllug] Re: Bizarre shell behaviour
Per Gregers Bilse
bilse at networksignature.com
Sat Nov 8 12:40:29 UTC 2003
> From: Dylan <dylan at dylan.me.uk>
> Subject: Re: [Gllug] Bizarre shell behaviour
>
> On Friday 07 November 2003 23:57 pm, Bruce Richardson wrote:
> > On Fri, Nov 07, 2003 at 11:27:51PM +0000, Dylan wrote:
> > > On Friday 07 November 2003 17:16 pm, Tethys wrote:
> > > > Take the following shell script. Run it:
> > > >
> > > > #!/bin/sh
> > > >
> > > > count=0
> > > > while read var
> > > > do
> > > > count=1
> > > > done < /etc/group
> > > >
> > > > echo $count
> > >
> > > Just out of interest (and 'cos I'm trying to learn shell scripting) can
> > > someone explain what this is supposed to achieve. The loop is obvious,
> > > but what's the redirection all about?
> >
> > It's reading from the file /etc/group, one line at a time.
>
> Thanks. I added an echo $var before the done and got a listing of the file so
> I figure each line is going into $var. How does this work then?
"man bash"; at some 80 pages, it makes for nice weekend reading.
To answer your question, keep in mind that shell constructs behave
like programs:
read line < /etc/group
will read the first line from /etc/group from stdin, and place the
contents in $line. When placed in a loop like this:
while read line
do
...
done < /etc/group
you may well wonder how come read(1) reads from /etc/group, they're
miles part in the code. The answer is that the loop actually looks
like this:
(
while read line
do
...
done
) < /etc/group
Thus, when read(1) tries to read something, its stdin will be connected
to stdin for the loop, which in turn reads from /etc/group, and the loop
will then run until read(1) fails, which it will upon EOF on stdin (ie,
trying to read beyond the end of /etc/group).
The same goes for output:
while read line
do
echo "$line"
done > /tmp/script.out < /etc/group
will make a copy a /etc/group.
Beware of typical mistake:
while read line < /etc/group
do
...
done
This will loop forever, reading the first line of /etc/group again
and again -- the file is opened (at least conceptually) each time
around the loop. And again for output:
while read line
do
echo "$line" > /tmp/script.out
done < /etc/group
will put the last line of /etc/group into /tmp/script.out.
Best,
-- Per
--
Gllug mailing list - Gllug at linux.co.uk
http://list.ftech.net/mailman/listinfo/gllug
More information about the GLLUG
mailing list