created on | January 18, 2022 |
In Bash shell programming you can use the usual suspects for loop structures: the for loop, which is usually used to iterate over a set of items, and the while and until loop structures, which both loop while a certain specified condition is met.
The for loop usually iterates over a set of items, and executes a block of statements and expressions for each item. The general form is:
The can be one of several types of item sets:
An infinite loop can be written by using an infinite item set:
An example of a for loop iterating over an array:
The same loop can be written with the array defined in the for statement:
You can iterate over a range with . The step rate can be omitted. The following for loop prints the numbers from 0 to 7:
While this for loop prints all even numbers from 0 to 7:
You can also reverse the range. The following for loop prints all even numbers from 7 to 0:
Ranges also work with characters. The following loop prints all lower case characters from a to e:
Ranges of characters can also be reversed and the step rate also works with characters. The following for loop prints the upper case characters E, C and A: letters
Well, not really C-style but rather roughly based on C. Here’s an example of a for loop that prints the numbers 0 to 7:
An infinite C-style for loop can be written by omitting start value, stop, value and step rate:
The step rate can be omitted and the variable defined in the for statement can be manipulated in the for body instead:
A while loop executes a block of statements and expressions as long as the condition specified in the while statement is true.
The general form of a while loop is:
can be anything that returns an exit status. An exit status of 0 means true, while an exit status of 1 means false.
I.e., printing the numbers from 0 to 7 with a while loop:
Or, with arithmetic expansion in the condition, which I find more legible, again the numbers 0 to 7 are printed:
An until loop executes a block of statements and expressions as long as the condition specified in the until statement is false.
The until loop below prints the numbers 0 to 7:
As with the while loop, can be anything that returns an exit status. An exit status of 0 means true, while an exit status of 1 means false.
Infinite while and until loops can be written with the command for while loops and for until loops, i.e.:
You might come across an alternative form of the while or until loop, which uses the bash builtin operator (colon), which evaluates its arguments and always returns true:
Of course, for an infinite until loop using the colon operator, the return code of must be inverted:
This application of the colon operator has been documented in the The UNIX Programming Environment manual:
" ":" is a shell built-in command that does nothing but evaluate its arguments and return "true". [...], we could have used true, which merely returns a true exit status. (There is also a false command.) But ':' is more efficient than true because it does not execute a command from the file system. "
The UNIX Programming Environment, Kernighan and Pike, 1984
Given the speed of harddisks back in 1984 this made sense in 1984. Nowadays, the speed advantage is negligible, thus it’s better to use the commands , or .
continue skips the statements and expressions of the block after the continue statement. Or, in other words. it’s a goto to the end of the block.
break immediately terminates the loop, that is, with break you immediately bail out of the loop.
In the following example, in the for statement the range of the numbers 0 to 7 is defined. When the block statments and expressions are executed, a value of 2 for the variable i causes the block to be continued at the beginning of the block, with the variable i incremented to the value 3. This happens before the printf statement, so the variable value 2 is not printed. The break statement together with the check of the variable i for a value of 4 causes an abort of the for loop after the value 4 has been printed. Thus, the following script prints out the numbers 0, 1, 3 and 4 and terminates thereafter: