- There are several Bash loop mechanisms. Pick the one which makes your code the easiest to follow.
While Loops
One of the easiest loops, the format:
while [ <some test> ] do <commands> done
Example:
#!/bin/bash counter=1 while [ $counter -le 10 ] do echo $counter (( counter++ )) done echo all done!
- There is no space before and after the equal sign
- There is space in after [ and before the ] , and after (( , before ))
Until Loops
The until loop is fairly similar to the while loop. The difference is that it will execute the commands within it until the test becomes true.
until [ <some test> ] do <commands> done
For Loops
The for loop is a little bit different to the previous two loops. What it does is say for each of the items in a given list, perform the given set of commands. It has the following syntax.
for var in <list> do <commands> done
The for loop will take each item in the list (in order, one after the other), assign that item as the value of the variable var, execute the commands between do and done then go back to the top, grab the next item in the list and repeat over.
The list is defined as a series of strings, separated by spaces.
Here is a simple example to illustrate:
#!/bin/bash
# Basic for loop
names='Stan Kyle Cartman'
for name in $names
do
echo $name
done
Range { }
eg. for age in {1..100}
for value in {0..5} do echo $value done echo All done for range!
Loop through files
We can use wildcards to loop through a folder and work on the files.
E.g look through current folder and change the extension name from html to php:
#!/bin/bash for value in *.html do cp $value $( basename -s .html $value ).php done
Break
The break statement tells Bash to leave the loop straight away. It may be that there is a normal situation that should cause the loop to end but there are also exceptional situations in which it should end as well. For instance, maybe we are copying files but if the free disk space get’s below a certain level we should stop copying.
copy_files.sh
#!/bin/bash
# Make a backup set of files
for value in $1/*
do
used=$( df $1 | tail -1 | awk '{ print $5 }' | sed 's/%//' )
if [ $used -gt 90 ]
then
echo Low disk space 1>&2
break
fi
cp $value $1/backup/
done
Continue
The continue statement tells Bash to stop running through this iteration of the loop and begin the next iteration. Sometimes there are circumstances that stop us from going any further. For instance, maybe we are using the loop to process a series of files but if we happen upon a file which we don’t have the read permission for we should not try to process it.
copy_check.sh
#!/bin/bash
# Make a backup set of files
for value in $1/*
do
if [ ! -r $value ]
then
echo $value not readable 1>&2
continue
fi
cp $value $1/backup/
done
Select
The select mechanism allows you to create a simple menu system. It has the following format:
select var in <list> do <commands> done
When invoked it will take all the items in list (similar to other loops this is a space separated set of items) and present them on the screen with a number before each item. A prompt will be printed after this allowing the user to select a number. When they select a number and hit enter the corresponding item will be assigned to the variable var and the commands between do and done are run. Once finished a prompt will be displayed again so the user may select another option.
A few points to note:
- No error checking is done. If the user enters something other than a number or a number not corresponding to an item then var becomes null (empty)
- If the user hits enter without entering any data then the list of options will be displayed again.
- The loop will end when an EOF signal is entered or the break statement is issued.
- You may change the system variable PS3 to change the prompt that is displayed.
Here is a simple example to illustrate it’s usage:
select_example.sh
#!/bin/bash
# A simple menu system
names='Kyle Cartman Stan Quit'
PS3='Select character: '
select name in $names
do
if [ $name == 'Quit' ]
then
break
fi
echo Hello $name
done
echo Bye