After some search on the Internet, it appears that Bash doesn't have a do-while loop.
Is this correct? Is there a reliable source to confirm this (the lack of evidence that there is a do-while loop is not an argument that there isn't one, perhaps a statement is only unpopular)?
Is it possible to define directives oneself and thus implement a do-while loop? There is an algorithmic way to transform a do-while-loop in a while-loop, but this is not the scope of this question.
bash
(or Posix shells in general) don't have an explicit syntax for a post-test loop (commonly known as a "do-while" loop) because the syntax would be redundant. The while
compound statement allows you to write pre-test, post-test or mid-test loops, all with the same syntax.
Here's the semantics of a shell while
loop, from Posix:
The format of the while loop is as follows:
while compound-list-1
do
compound-list-2
done
The compound-list-1 shall be executed, and if it has a non-zero exit status, the while command shall complete. Otherwise, the compound-list-2 shall be executed, and the process shall repeat.
A "compound list" is a sequence of commands; the exit status of a compound list is the exit status of the last command in the list.
That means that you could think of a while
loop as being written as follows:
while
optional-pre-test-compound-list
condition
do
post-test-compound-list
done
That is, there is no requirement that the condition to be tested immediately follows the while keyword. So the equivalent to the C syntax:
do statements while (test);
is
while statements; test do :; done
The :
between the do and the done is required, because the shell grammar does not allow empty statements. Since :
is not a metacharacter, it must have whitespace or a metacharacter before and after it; otherwise, it would be parsed as part of the preceding or succeeding token. Since it's parsed as a command, it also needs a semicolon or newline after it; otherwise the done
is treated as an argument to :
.