The while construct allows for repetitive execution of a list of commands, as long as the command controlling the while loop executes successfully (exit status of zero). The syntax is:
while CONTROL-COMMAND; do CONSEQUENT-COMMANDS; done
CONTROL-COMMAND can be any command(s) that can exit with a success or failure status. The CONSEQUENT-COMMANDS can be any program, script or shell construct.
As soon as the CONTROL-COMMAND fails, the loop exits. In a script, the command following the done statement is executed.
The return status is the exit status of the last CONSEQUENT-COMMANDS command, or zero if none was executed.
Here is an example for the impatient:
#!/bin/bash # This script opens 4 terminal windows. i="0" while [ $i -lt 4 ] do xterm & i=$[$i+1] done |
The example below was written to copy pictures that are made with a webcam to a web directory. Every five minutes a picture is taken. Every hour, a new directory is created, holding the images for that hour. Every day, a new directory is created containing 24 subdirectories. The script runs in the background.
Note the use of the true statement. This means: continue execution until we are forcibly interrupted (with kill or Ctrl+C).
This small script can be used for simulation testing; it generates files:
#!/bin/bash # This generates a file every 5 minutes while true; do touch pic-`date +%s`.jpg sleep 300 done |
Note the use of the date command to generate all kinds of file and directory names.
This script can be interrupted by the user when a Ctrl+C sequence is entered:
#!/bin/bash # This script provides wisdom FORTUNE=/usr/games/fortune while true; do echo "On which topic do you want advice?" cat << topics politics startrek kernelnewbies sports bofh-excuses magic love literature drugs education topics echo echo -n "Make your choice: " read topic echo echo "Free advice on the topic of $topic: " echo $FORTUNE $topic echo done |
A here document is used to present the user with possible choices. And again, the true test repeats the commands from the CONSEQUENT-COMMANDS list over and over again.
This script calculates the average of user input, which is tested before it is processed: if input is not within range, a message is printed. If q is pressed, the loop exits:
#!/bin/bash # Calculate the average of a series of numbers. SCORE="0" AVERAGE="0" SUM="0" NUM="0" while true; do echo -n "Enter your score [0-100%] ('q' for quit): "; read SCORE; if (("$SCORE" < "0")) || (("$SCORE" > "100")); then echo "Be serious. Common, try again: " elif [ "$SCORE" == "q" ]; then echo "Average rating: $AVERAGE%." break else SUM=$[$SUM + $SCORE] NUM=$[$NUM + 1] AVERAGE=$[$SUM / $NUM] fi done echo "Exiting." |
Note how the variables in the last lines are left unquoted in order to do arithmetic.