Lost Assignment of var in shell for loop with stdout redirection

Dennis Bednar dennis at rlgvax.UUCP
Wed Feb 4 07:56:48 AEST 1987


While writing a shell script, I found an unexpected behavior
that I thought I would share with the net.

In summary, apparently

for i
do
	var=xxx
done >/tmp/tmpfile

causes the shell interpreter to run a sub-shell, and so the value
of $var set in the middle of a for loop is lost if $var is referenced
after the for loop.  IS THIS CONSIDERED TO BE A sh(1) bug?

The first shell script below named "t" fails, in that if run as
"t -A", it prints AFLAG = 0, not AFLAG = 1, at the end, even though
AFLAG is set to 1 in the for loop.  However, if, the
">/tmp/t$$" is removed from the file "t", the problem goes away.
Since I needed to capture the output into a temp file /tmp/t$$,
I fixed it by modifying "t" to save the AFLAG variable in a temp file.
The fixed version I came up with is called "t2".


Here is the output, when run on our machine (cci632 Sys5 r2):
Script started on Tue Feb  3 16:35:35 1987
$ t -A
1: AFLAG = 1
2: AFLAG = 0
$ t2 -A
1: AFLAG = 1
2: AFLAG = 1
$ 
script done on Tue Feb  3 16:35:47 1987

Below are two very short scripts "t" and "t2".


#--------------- CUT HERE ---------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	t
#	t2
# This archive created: Tue Feb  3 16:45:34 EST 1987
#
if test -f t
then
echo shar: will not over-write existing file 't'
else
echo x - t
# ............    F  I   L   E      B  E  G  .......... t
cat << '\SHAR_EOF' > t
AFLAG=0
for i
do
	if [ $i = -A ]
	then
		AFLAG=1
		echo "1: AFLAG = $AFLAG" 1>&2 # to stderr not to tmp file
		continue
	fi
done >/tmp/t$$
echo 2: AFLAG = $AFLAG
rm -f /tmp/t$$
\SHAR_EOF
# ............    F  I   L   E      E  N  D  .......... t
fi # end of overwriting check
if test -f t2
then
echo shar: will not over-write existing file 't2'
else
echo x - t2
# ............    F  I   L   E      B  E  G  .......... t2
cat << '\SHAR_EOF' > t2
AFLAG=0
for i
do
	if [ $i = -A ]
	then
		AFLAG=1
		echo "1: AFLAG = $AFLAG" 1>&2 # to stderr not to tmp file
		echo $AFLAG >/tmp/T$$		# pass flag via file
		continue
	fi
done >/tmp/t$$
AFLAG=`cat /tmp/T$$`
echo 2: AFLAG = $AFLAG
rm -f /tmp/t$$ /tmp/T$$
\SHAR_EOF
# ............    F  I   L   E      E  N  D  .......... t2
fi # end of overwriting check
# end of shell archive
exit 0
-- 
FullName:	Dennis Bednar
UUCP:		{seismo|sundc}!rlgvax!dennis
USMail:		CCI; 11490 Commerce Park Dr.; Reston VA 22091
Telephone:	+1 703 648 3300



More information about the Comp.unix.wizards mailing list