1. Looping with while and until
The syntax of the while
command is as follows:
while commands; do commands; done
-
A simple example:
while-count.sh
#!/bin/bash
# while-count: display a series of numbers
count=1
while [[ "$count" -le 5 ]]; do
echo "$count"
count=$((count + 1))
done
echo "Finished."vim while-count.sh
./while-count.sh
-
We can use a
while
loop to improve the menu program from the previous lesson:while-menu.sh
#!/bin/bash
# while-menu: a menu driven system information program
DELAY=3 # Number of seconds to display results
while [[ "$REPLY" != 0 ]]; do
clear
cat <<- _EOF_
Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
_EOF_
read -p "Enter selection [0-3] > "
if [[ "$REPLY" =~ ^[0-3]$ ]]; then
if [[ $REPLY == 1 ]]; then
echo "Hostname: $HOSTNAME"
uptime
sleep "$DELAY"
fi
if [[ "$REPLY" == 2 ]]; then
df -h .
sleep "$DELAY"
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"
fi
else
echo "Invalid entry."
sleep "$DELAY"
fi
done
echo "Program terminated."vim while-menu.sh
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 to0
and the menu is displayed again, giving the user the opportunity to make another selection. At the end of each action, asleep
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. OnceREPLY
is equal to0
, indicating the “quit” selection, the loop terminates and execution continues with the line followingdone
../while-menu.sh
-
Inside a loop in bash we can use
break
andcontinue
.while-menu2.sh
#!/bin/bash
# while-menu: a menu driven system information program
DELAY=3 # Number of seconds to display results
while true; do
clear
cat <<- _EOF_
Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
_EOF_
read -p "Enter selection [0-3] > "
if [[ "$REPLY" == 0 ]]; then
break
fi
if [[ ! "$REPLY" =~ ^[0-3]$ ]]; then
echo "Invalid entry."
sleep "$DELAY"
continue
fi
if [[ $REPLY == 1 ]]; then
echo "Hostname: $HOSTNAME"
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
done
echo "Program terminated."vim while-menu2.sh
./while-menu2.sh
-
The
until
loop is very similar to thewhile
loop, but with a negated condition.until-count.sh
#!/bin/bash
# until-count: display a series of numbers
count=1
until [[ "$count" -gt 5 ]]; do
echo "$count"
count=$((count + 1))
done
echo "Finished."vim until-count.sh
./until-count.sh
-
We can also read the standard input with
while
anduntil
:cat distros.txt
while-read.sh
#!/bin/bash
# while-read: read lines from a file
while read distro version release
do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
"$distro" \
"$version" \
"$release"
done < distros.txtvim while-read.sh
The
while
loop will continue as long as theread
command is successful getting input from stdin, and we redirect stdin to get data from the filedistros.txt
(by using the operator<
at the end of thewhile
command)../while-read.sh
We can also use a pipe (
|
) to redirect the stdin:while-read2.sh
#!/bin/bash
# while-read2: read lines from a file
sort -k 1,1 -k 2n distros.txt | \
while read distro version release; do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
"$distro" \
"$version" \
"$release"
donevim while-read2.sh
Notice that we are breaking long commands by adding a
\
at the end of a line, in order to make the program more readable and clear../while-read2.sh