The shell provides several ways to loop through a set of commands. A loop allows you to repeatedly execute a block of commands before proceeding further in the script. The two main types of loop are for and while. until loops are a variation on while loops. In addition, the select command can be used to repeatedly present a selection menu.
The for loop executes a block of commands once for each member of a list. The basic format is
for i in list do commands done
The variable i in the example can have any name that you choose.
You can use for loops to repeat a command a fixed number of times. For example, if you enter the following on the command line,
$ for x in 0 1 2 3 4 5 6 7 8 9 > do > touch testfile$x > done
the shell will run the touch command ten times. Each time, it will create an empty file with the name testfile followed by a number.
If you omit the in list portion of the for loop, the value of $* will be used instead. That will cause the command block between do and done to be executed once for each positional parameter You could use this to iterate through the command-line arguments to a script. For example, the following script can be used to look up several people in the file called friends:
# # contacts - takes names as arguments # looks up each name in the friends file # for NAME do grep $NAME $HOME/friends done
If you issue the command
$ contacts John Dave Albert Rachel
the grep command will be run four times-first for John, then for Dave, then for Albert, and finally for Rachel.
Loops can be nested. Each of the loops must use a different variable name. For example, the following script iterates through the files in the current directory. For each file, it runs the script proof five times.
for FILENAME in * do echo "Printing 5 copies of $FILENAME" for x in 1 2 3 4 5 do proof $FILENAME done done
The while command repeats a block of commands based on the result of a logical test. The general form for the use of while is
while testcommand do commandlist done
When while is executed, it runs testcommand. If the return value of testcommand is true, commandlist is executed, and the program returns to the while test. The loop continues until the value of testcommand is false, at which point while terminates.
This while loop prints the squares of the integers from 1 to 10.
i=1 while [ $i -le 10] do expr $i \* $i i='expr $i + 1' done
The until command is the complement of the while command, and its form and usage are similar. The only difference between them is that while loops repeat until the test is false, and until loops repeat until the test is true. Thus, the preceding example could also be written as
i=1 until [ $i -gt 10] do expr $i \* $i i='expr $i + 1' done
Normally, execution of a loop continues until the logical condition of the loop is met. Sometimes, however, you want to exit a loop early or skip certain commands.
break exits from a loop. The script resumes execution with the first command after the loop. In a set of nested loops, break exits the immediately enclosing loop. If you give break a numeric argument, the program breaks out of that number of loops, so for example, break 3 would exit a set of three nested loops all at once.
continue sends control back to the top of the smallest enclosing loop. If an argument is given, control goes to the top of the nth enclosing loop.
The commands true and false are very simple-true simply returns a successful exit status, and false generates an unsuccessful exit status. The primary use of these two commands is in setting up infinite loops. For example,
while true do read NEWLINE if [ $NEWLINE = "."] then break fi done
This loop will execute forever-or at least until the user enters a dot on a line by itself. Infinite loops should be used sparingly, since they are often difficult to read and to debug.
ksh and bash provide another iteration command, select. The select command displays a numbered list of items on standard error and waits for input. After the selection is processed, the user is prompted for input again, and so on until the loop ends (usually with a break statement).
For example, you could write a script to help new users execute common programs. The select command provides a menu of alternatives from which to choose. The variable PS3 is used to prompt for input. A case statement is used in the script to execute the chosen command. (You could use an if statement, if you prefer.) If a user presses ENTER without making a selection, the list of items is displayed again.
#!/bin/bash # startMenu - Provide a menu of common actions. PS3='What would you like to do? (enter 13) ' select ACTION in "Read Mail with Pine" "Start XWindows" "Exit this Menu" do case $ACTION in "Read Mail with Pine") # run the pine mailreader; return to this menu when done pine ;; "Start XWindows") # start XWindows, and do not return to this script # replace this process with the X process exec startx ;; "Exit this Menu") echo "Returning to your login shell." break ;; *) echo "Response not recognized, try again." ;; esac done
In this example, the selection is saved in the variable ACTION. For example, entering “1” would set ACTION to “Read Mail”. If the user selects a number outside the appropriate range, the variable is set to null, and in this example is caught by the last case block. When you run this script, the output will look like this:
$ startMenu 1) Read Mail 2) Start XWindows 3) Exit this Menu What would you like to do? (enter 13)