[Gllug] Bizarre shell behaviour
Steve Cobrin
steve.cobrin at highbury.demon.co.uk
Wed Nov 12 13:52:08 UTC 2003
On Friday 07 November 2003 17:16, Tethys wrote:
> Take the following shell script. Run it:
>
> #!/bin/sh
>
> count=0
> while read var
> do
> count=1
> done < /etc/group
>
> echo $count
>
> Assuming /etc/group isn't empty (which it isn't), the script should
> echo 1, right? Well the answer is, it depends on the shell. Under
> bash, pdksh and genuine ksh, yes, it does. But under Bourne shell,
> it varies. Under AIX and OpenBSD, sure enough it echoes a 1. But
> under Solaris and Tru64, it echoes 0 instead.
>
> It's related to the "< /etc/group". If you remove that, and externally
> pipe the contents into the script, it works.
>
> Bizarre... any ideas why? Judicious use of debugging echo statements
> shows that count is indeed being set to 1 inside the loop, but is being
> reset to 0 when the loop exits.
If its the Bash shell it will behave as expected. However with a normal Bourne
shell it won't!
Because, by doing a redirect into the while loop, you effectively create a
subshelled process, where $count is implicitly exported to, but can't be
changed, therefore at the end of the loop, $count is reset to its original
value 0. This is documented in various shell programming books.
The workaround, is to avoid creating a subshell, through sneaky redirection
#!/bin/sh
count=0
exec 9<&0
exec < /etc/group
while read
do
count=`exec $count + 1`
done
exec 0>&9
exec 9>&-
echo $count
So when doing traditional Bourne shell programming one must be very careful
when redirecting and expecting variable to be updated
regards
Steve
--
Gllug mailing list - Gllug at linux.co.uk
http://list.ftech.net/mailman/listinfo/gllug
More information about the GLLUG
mailing list