[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