Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!vrdxhq!bdmrrr!rlgvax!dennis From: dennis@rlgvax.UUCP (Dennis Bednar) Newsgroups: comp.unix.wizards,comp.unix.questions Subject: Lost Assignment of var in shell for loop with stdout redirection Message-ID: <354@rlgvax.UUCP> Date: Tue, 3-Feb-87 16:56:48 EST Article-I.D.: rlgvax.354 Posted: Tue Feb 3 16:56:48 1987 Date-Received: Sat, 7-Feb-87 04:17:12 EST Organization: Computer Consoles Inc, Reston VA Lines: 100 Xref: mnetor comp.unix.wizards:858 comp.unix.questions:968 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