Making a for Loop with Multiple Variables

The normal Bourne shell for loop (Section 35.21) lets you take a list of items, store the items one by one in a shell variable, and loop through a set of commands once for each item:

for file in prog1 prog2 prog3
do
   ...process $file
done

I wanted a for loop that stores several different shell variables and makes one pass through the loop for each set of variables (instead of one pass for each item, as a regular for loop does). This loop does the job:

set Section 35.25

for bunch in "ellie file16" "donna file23" "steve file34"
do
   # PUT FIRST WORD (USER) IN $1, SECOND (FILE) IN $2...
   set $bunch
   mail $1 < $2
done

If you have any command-line arguments and still need them, store them in another variable before you use the set command. Or you can make the loop this way:

while read line ; do
    eval $line
    mail -s "$s" $u < $f
done <<"EOF"
    u=donna f=file23 s=’a memo’
    u=steve f=file34 s=report
    u=ellie f=file16 s=’your files’done
EOF

This script uses the shell's eval (Section 27.8) command to rescan the contents of the bunch variable and store it in separate variables. Notice the single quotes, as in s='your files'; this groups the words for eval. The shell removes the single quotes before it stores the value into the s variable.

— JP