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