29 - Flow Control: Looping With /: While Until
29 - Flow Control: Looping With /: While Until
Looping
Daily life is full of repeated activities. Going to work each day, walking the dog, and slic-
ing a carrot are all tasks that involve repeating a series of steps. Let’s consider slicing a
carrot. If we express this activity in pseudocode, it might look something like this:
1. get cutting board
2. get knife
3. place carrot on cutting board
4. lift knife
5. advance carrot
6. slice carrot
7. if entire carrot sliced, then quit; else go to step 4
Steps 4 through 7 form a loop. The actions within the loop are repeated until the condi-
tion, “entire carrot sliced,” is reached.
423
29 – Flow Control: Looping with while / until
while
bash can express a similar idea. Let’s say we wanted to display five numbers in sequen-
tial order from 1 to 5. a bash script could be constructed as follows:
#!/bin/bash
count=1
424
Looping
#!/bin/bash
_EOF_
read -p "Enter selection [0-3] > "
425
29 – Flow Control: Looping with while / until
By enclosing the menu in a while loop, we are able to have the program repeat the menu
display after each selection. The loop continues as long as REPLY is not equal to 0 and
the menu is displayed again, giving the user the opportunity to make another selection. At
the end of each action, a sleep command is executed so the program will pause for a
few seconds to allow the results of the selection to be seen before the screen is cleared
and the menu is redisplayed. Once REPLY is equal to 0, indicating the “quit” selection,
the loop terminates and execution continues with the line following done.
#!/bin/bash
while true; do
clear
cat <<- _EOF_
Please Select:
_EOF_
read -p "Enter selection [0-3] > "
426
Breaking Out of a Loop
uptime
sleep "$DELAY"
continue
fi
if [[ "$REPLY" == 2 ]]; then
df -h
sleep "$DELAY"
continue
fi
if [[ "$REPLY" == 3 ]]; then
if [[ "$(id -u)" -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh "$HOME"
fi
sleep "$DELAY"
continue
fi
if [[ "$REPLY" == 0 ]]; then
break
fi
else
echo "Invalid entry."
sleep "$DELAY"
fi
done
echo "Program terminated."
In this version of the script, we set up an endless loop (one that never terminates on its
own) by using the true command to supply an exit status to while. Since true will
always exit with an exit status of zero, the loop will never end. This is a surprisingly com-
mon scripting technique. Since the loop will never end on its own, it’s up to the program-
mer to provide some way to break out of the loop when the time is right. In this script, the
break command is used to exit the loop when the 0 selection is chosen. The con-
tinue command has been included at the end of the other script choices to allow for
more efficient execution. By using continue, the script will skip over code that is not
needed when a selection is identified. For example, if the 1 selection is chosen and iden-
tified, there is no reason to test for the other selections.
427
29 – Flow Control: Looping with while / until
until
The until command is much like while, except instead of exiting a loop when a non-
zero exit status is encountered, it does the opposite. An until loop continues until it re-
ceives a zero exit status. In our while-count script, we continued the loop as long as
the value of the count variable was less than or equal to 5. We could get the same result
by coding the script with until.
#!/bin/bash
count=1
By changing the test expression to $count -gt 5, until will terminate the loop at
the correct time. The decision of whether to use the while or until loop is usually a
matter of choosing the one that allows the clearest test to be written.
#!/bin/bash
428
Reading Files with Loops
To redirect a file to the loop, we place the redirection operator after the done statement.
The loop will use read to input the fields from the redirected file. The read command
will exit after each line is read, with a zero exit status until the end-of-file is reached. At
that point, it will exit with a non-zero exit status, thereby terminating the loop. It is also
possible to pipe standard input into a loop.
#!/bin/bash
Here we take the output of the sort command and display the stream of text. However,
it is important to remember that since a pipe will execute the loop in a subshell, any vari-
ables created or assigned within the loop will be lost when the loop terminates.
Summing Up
With the introduction of loops and our previous encounters with branching, subroutines
and sequences, we have covered the major types of flow control used in programs. bash
has some more tricks up its sleeve, but they are refinements on these basic concepts.
Further Reading
● The Bash Guide for Beginners from the Linux Documentation Project has some
more examples of while loops:
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html
● The Wikipedia has an article on loops, which is part of a larger article on flow
control:
http://en.wikipedia.org/wiki/Control_flow#Loops
429