Bash – What does “while :;” mean

bashshell-script

I know what a while loop is. However, I've only seen it work with:

while [condition]
while ![condition]
while TRUE (infinite loop)

Where the statement after while has to be either TRUE or FALSE.

There is a shell builtin command named :. It is described as a dummy command doing nothing, but I do not know if it is the same here, even if can it be TRUE or FALSE. Maybe it is something different, but what?

Best Answer

The syntax is:

while
  first list of commands
do
  second list of commands
done

which runs the second list of commands in a loop as long as the first list of commands (so the last run in that list) is successful.

In that first list of commands, you can use the [ command to do various kinds of tests, or you can use the : null command that does nothing and returns success, or any other command.

while :; do cmd; done

Runs cmd over and over forever as : always returns success. That's the forever loop. You could use the true command instead to make it more legible:

while true; do cmd; done

People used to prefer : as : was always builtin while true was not (a long time ago; most shells have true builtin nowadays)¹.

Other variants you might see:

while [ 1 ];  do cmd; done

Above, we're calling the [ command to test whether the "1" string is non-empty (so always true as well)

while ((1)); do cmd; done

Using the Korn/bash/zsh ((...)) syntax to mimic the while(1) { ...; } of C.

Or more convoluted ones like until false; do cmd; done, until ! true...

Those are sometimes aliased like:

alias forever='while :; do'

So you can do something like:

forever cmd; done

Few people realise that the condition is a list of commands. For instance, you see people writing:

while :; do
  cmd1
  cmd2 || break
  cmd3
done

When they could have written:

while
  cmd1
  cmd2
do
  cmd3
done

It does make sense for it to be a list as you often want to do things like while cmd1 && cmd2; do...; done which are command lists as well.

In any case, note that [ is a command like any other (though it's built-in in modern Bourne-like shells), it doesn't have to be used solely in the if/while/until condition lists, and those condition lists don't have to use that command more than any other command.


¹ : is also shorter and accepts arguments (which it ignores). While the behaviour of true or false is unspecified if you pass it any argument. So one may do for instance:

while : you wait; do
  something
done

But, the behaviour of:

until false is true; do
  something
done

is unspecified (though it would work in most shell/false implementations).

Related Question