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