root@lingua.cltr.uq.OZ.AU (Hulk Hogan) (03/05/91)
Hi. I guess this is probably a FAQ, but here goes anyway... Platform: Sun4. OS: SunOS 4.x. I have written some Bourne shell script which sets some variables within the body of a while loop. After the loop finishes, the variables are no longer set. How can I retain these values after the while loop? I've tried an export within the body of the while, but that didn't work. I remember reading somewhere that the body of a while loop is executed in sub-shell, and that's why the behavious occurs. I really don't care how the shell does while loops. I just want my variables! I can use a combination of head, tail and cut to get the results I want, but it would be so much easier if I could just use while. Code fragment to assign field 1 of line number $choice to $minuid and field 2 of it to $maxuid follows. | num=0 | while [ $num -le $choice ] | do | read minuid maxuid title | echo "DEBUG: $num $title $minuid $maxuid" | num=`expr $num + 1` | done < $UIDRANGES | | echo "After while loop: num=$num title=$title minuid=$minuid maxuid=$maxuid" /\ndy -- Andrew M. Jones, Systems Programmer, Internet: andy@lingua.cltr.uq.oz.au Centre for Lang. Teaching & Research, Phone (Australia): (07) 365 6915 University of Queensland, St. Lucia, Phone (World): +61 7 365 6915 Brisbane, Qld. AUSTRALIA 4072 Fax: +61 7 365 7077 "No matter what hits the fan, it's never distributed evenly....."
mcgrew@ichthous.Eng.Sun.COM (Darin McGrew) (03/07/91)
root@lingua.cltr.uq.OZ.AU (Hulk Hogan) writes: >Hi. I guess this is probably a FAQ, but here goes anyway... >Platform: Sun4. OS: SunOS 4.x. >I have written some Bourne shell script which sets some variables within >the body of a while loop. After the loop finishes, the variables are no >longer set. How can I retain these values after the while loop? >I've tried an export within the body of the while, but that didn't work. > >I remember reading somewhere that the body of a while loop is executed in >sub-shell, and that's why the behavious occurs. I really don't care how >the shell does while loops. I just want my variables! If the while loop has its stdio redirected in any way, it is put in a subshell. (Likewise with for loops, case statements, etc.) The subshell has no way to pass variables back to its parent shell. >I can use a combination of head, tail and cut to get the results I >want, but it would be so much easier if I could just use while. Another approach would be to write the values of the variables into temporary files, and then read them back, but that isn't really a great solution either. I'd try avoiding putting the while loop into a subshell by doing the io redirection in the parent shell. Your example becomes-- exec < $UIDRANGES num=0 while [ $num -le $choice ] do read minuid maxuid title echo "DEBUG: $num $title $minuid $maxuid" num=`expr $num + 1` done < $UIDRANGES echo "After while: num=$num title=$title minuid=$minuid maxuid=$maxuid" If you need your original io at some point after the while loop, there are games you can play with `exec 3<&0` and `exec 0<&3` to save stdin as file descriptor 3 (typically unused) beforehand, and then restore stdin from file descriptor 3 when you're done. Darin McGrew mcgrew@Eng.Sun.COM "Christianity isn't a crutch; it's a stretcher. Affiliation stated for You can't even hobble into heaven." identification purposes only.
mcgrew@ichthous.Eng.Sun.COM (Darin McGrew) (03/07/91)
In article <9209@exodus.Eng.Sun.COM> I write: >I'd try avoiding putting the while loop into a subshell by doing >the io redirection in the parent shell. Your example becomes-- > > exec < $UIDRANGES > num=0 > while [ $num -le $choice ] > do > read minuid maxuid title > echo "DEBUG: $num $title $minuid $maxuid" > num=`expr $num + 1` > done < $UIDRANGES > > echo "After while: num=$num title=$title minuid=$minuid maxuid=$maxuid" This should really be-- exec < $UIDRANGES num=0 while [ $num -le $choice ] do read minuid maxuid title echo "DEBUG: $num $title $minuid $maxuid" num=`expr $num + 1` done echo "After while: num=$num title=$title minuid=$minuid maxuid=$maxuid" since the point was to eliminate the io redirection of the while loop. Darin McGrew mcgrew@Eng.Sun.COM "Christianity isn't a crutch; it's a stretcher. Affiliation stated for You can't even hobble into heaven." identification purposes only.
jik@athena.mit.edu (Jonathan I. Kamens) (03/07/91)
In article <9209@exodus.Eng.Sun.COM>, mcgrew@ichthous.Eng.Sun.COM (Darin McGrew) writes: |> If the while loop has its stdio redirected in any way, it is put |> in a subshell. (Likewise with for loops, case statements, etc.) |> The subshell has no way to pass variables back to its parent |> shell. I just want to point out that this problem is eliminated in some newer versions of the bourne shell, and also in some other shells (including, I believe, bash and ksh) that use the bourne shell's language. Of course, the C shell gets around the problem by not allowing redirection into loops at all :-). -- Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8085 Home: 617-782-0710