[comp.unix.questions] Bourne shell oddity

de5@STC06.CTD.ORNL.GOV (SILL D E) (08/07/90)

What should the following script do?

#!/bin/sh
foo=bar
while true
do
    if [ $foo = bar ]
    then
        foo=baz
        echo foo=${foo}
        break
    fi
done </dev/null
echo foo=${foo}

I would have expected it to output:

foo=baz
foo=baz

But I get:

foo=baz
foo=bar

Removing the input redirection from the while-loop gives the expected
result. 

Question:  Is this a bug, or is I/O redirection of commands supposed
to affect variable scoping somehow?  I couldn't find anything in the
FM to explain this behavior.

Another Question:  Is there a simple workaround, preferably something
more elegant than passing values in files?

Please reply by mail; I don't follow this group/list.

Thanks.

--
Dave Sill (de5@ornl.gov)
Martin Marietta Energy Systems
Workstation Support

maart@cs.vu.nl (Maarten Litmaath) (08/08/90)

In article <9008071535.AA01487@stc06.CTD.ORNL.GOV>,
	de5@STC06.CTD.ORNL.GOV (SILL D E) writes:
)...
)#!/bin/sh
)foo=bar
)while true
)do
)    if [ $foo = bar ]
)    then
)        foo=baz
)        echo foo=${foo}
)        break
)    fi
)done </dev/null
)echo foo=${foo}

Most current implementations: foo=bar.
POSIX requires: foo=baz.

)...
)Another Question:  Is there a simple workaround, preferably something
)more elegant than passing values in files?

	foo=bar

	# dup(2) file descriptor 0 to fd 9,
	# then connect fd 0 (== stdin) to /dev/null
	exec 9<&0 < /dev/null

	while true
	do
		...
	done

	# dup() fd 9 back to fd 0,
	# i.e. reconnect fd 0 to the original stdin, then close fd 9
	exec 0<&9 9<&-

	echo foo=$foo
--
   "UNIX was never designed to keep people from doing stupid things, because
    that policy would also keep them from doing clever things."  (Doug Gwyn)