The While Loop
In common with most programming languages, Unix shell scripting caters for instructions to be carried out repetitively.
The while loop will repeat a list of commands as long as a given condition is true. All of the conditional statements used in the if…fi construct can be used here, including string and numeric comparisons, file checking, null checking and the exit status of a command. The syntax is
while condition
do
list of commands
done
As an example, let’s write a script named table that will take a number as a command line argument, and print its ‘times table’. The sample below shows the output we would expect from the script:
$ table 5
1 times 5 is 5
2 times 5 is 10
3 times 5 is 15
4 times 5 is 20
5 times 5 is 25
6 times 5 is 30
7 times 5 is 35
8 times 5 is 40
9 times 5 is 45
10 times 5 is 50
11 times 5 is 55
12 times 5 is 60
To achieve this, we will need a variable that will act as a counter. This will begin at 1 and be incremented within the loop. The loop will keep repeating while the counter is less than 13. Within the loop, we will multiply the command line argument $1 by the counter, display the result of this sum, and increment the counter.
The table script is shown below.
counter=1
while [ $counter -lt 13 ]
do
calc=$(( $counter * $1 ))
echo $counter times $1 is $calc
counter=$(( $counter + 1 ))
done
There are two additional commands that can be used within loops. The break command breaks out of the loop, even though the terminating condition has not yet been met. The continue command goes back to the beginning of the loop without executing any subsequent commands. If the condition controlling the loop is still true, the loop will be repeated.
A loop can be coded to repeat itself infinitely, using the construct while true. This can be used for repeated checking of some aspect of the system. Generally, in this kind of loop, the user is given the option to quit the loop, although he can simply terminate it using the interrupt key.
The following script will display the number of processes which the current user has running, giving him an option to list the processes. He can also opt to quit the script. A delay of 10 seconds is introduced into the loop by using the sleep command that pauses for a given number of seconds.
while true
do
sleep 10
set $(ps -u $LOGNAME | wc)
echo You have $1 processes running
echo Enter l to list them, q to quit or c to continue
read u_reply
if [ $u_reply = q ]
then
break
fi
if [ $u_reply = c ]
then
continue
fi
ps -u $LOGNAME
done
The command set $(ps –u $LOGNAME | wc) lists processes belonging to the current login name and pipes the output to the wc command. This returns the number of words, lines and bytes contained in the answer. This output is used to set the script arguments $1 etc. The first of these arguments, the number of lines returned by the ps command, will be the number of processes this user has running. This is displayed to the user.
If he chooses to continue without listing the processes, the continue command returns to the beginning of the loop. If he chooses to quit, the break command breaks out of the loop. Otherwise, the script will carry out he second ps command that lists all the processes.