21. Loops

Bash supports three different types of loops. The until loop executes a list of commands until the test command exits not on success:

$ a=0
$ until (( a > 2 ))
do
  echo $a
  let a+=1;
done

The loop body is always encapsulated with the keywords do and done. The while loop executes a list of commands as long as the test command exits on success:

$ a=3
$ while (( a > 0 ))
do
  echo $a
  let a-=1
done

A defined number of iterations can be done by the for loop:

$ for file in *
do
  echo $file
done

The for loop iterates over the words which were expanded by the filename expansion "*". Before the commands of the loop body are executed, each word is saved once in the loop variable file. The for loop can also be written as in C:

$ files=(*)
$ for ((i = 0; i<${#files[@]}; i++))
do
  echo ${files[$i]};
done

The loop variable i is initialized by the first expression within the round brackets after the keyword for. As long as the second expression is expanded by arithmetic expansion to true the commands from the loop body are executed once. Afterwards the third command of the loop head is executed. An endless loop can be written by:

while [ 1 ]
do
  echo "Press [CTRL]+[C] to escape from the command";
done

To cancel the execution of a loop the break command is used:

while [ 1 ]
do
  echo "I will terminate";
  break;
done

To proceed with the next iteration before reaching the end of the function body, the continue command is used:

$ while [ 1 ]
do
  continue
  echo "never reached";
done

Loops can be nested:

$ for((i=0; i<3; i++))
do
  for((j=0; j<3; j++))
  do
    echo "($i,$j)";
  done
done

To break the execution of the nth loop, the break command with label n is used:

$ while [ 1 ]
do
  while [ 1 ]
  do
    echo "reached only once";
    break 2;
  done
done

The first surrounding loop of the break command is referenced by 1, the second by 2. To continue the nth loop is done similar by the continue command. The output of loops can also be redirected:

$ for((i=0; i<3; i++))
do
  echo -n "$i**2=";
  echo $((i**2));
done > results