Bourne Shell FOR loop confusion

Jerry Peek jdpeek at RODAN.ACS.SYR.EDU
Mon Aug 14 00:25:05 AEST 1989


In article <2346 at wyse.wyse.com> bob at wyse.UUCP (Bob McGowen Wyse Technology Training) writes:
> ... what you do in the loop may not be available to your script
> outside of the loop.  One way around this would be to save items
> in a tmp file and either read the tmp file as needed or perhaps
> use the dot command on it:
> 
> 	. tmp

I think this is a good technique to know, so I decided to post an
example of the fix I use.  Inside the loop, I use "echo" commands to
spit out variable-definition commands.  I hook the output of 'echo'
onto a less-used file descriptor like 4 -- and catch fd4 into a file
at the end of the loop.

This code fragment reads in /etc/passwd.  After the loop, you can get
the first username from $user1, the first uid in $uid1, 20th username
from $user20, and so on...  This particular example is a quick-and-dirty
way to get Bourne Shell "arrays", but it works just as well for plain ol'
single-value shell variables:

	defs=/tmp/defs$$
	IFS=":$IFS"   # TO PARSE :-SEPARATED FIELDS
	line=0

	# READ /etc/passwd A LINE AT A TIME; STORE GOOD STUFF IN
	# VARIABLES IN $defs FILE BECAUSE LOOP IS RUN IN A SUB-SHELL:
	while read user passwd uid junk
	do
	   line=`expr $line + 1`
	   echo "user${line}='$user' uid${line}='$uid'" 1>&4
	done </etc/passwd 4>$defs

	. $defs   # READ VARIABLE DEFINITIONS INTO THIS SHELL

The $defs file gets lines like this:
	user23='freddie' uid23='1032'
	user24='alice' uid24='1048'
then, after the ". $defs" command, you can access $user23, $uid23, etc.

BTW, it's more efficient to use "echo 1>&4" and "done 4>$defs",
because the $defs file is only opened once while the loop runs.
On the other hand, if you simply put "echo >>$defs" into the loop,
the shell has to open and close the $defs file for each pass of the loop.

--Jerry Peek; Syracuse University Academic Computing Services; Syracuse, NY
  jdpeek at rodan.acs.syr.edu///JDPEEK at SUVM.BITNET///GEnie: J.PEEK1
  +1 315 443-3995



More information about the Comp.unix.questions mailing list