What does "while :;" mean?

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).


while : is an infinite loop. : just does nothing (successfully).

So if you want your shell to hang forever doing nothing, you can write it as

while :
do
    :
done

Or in a single line with ; instead of newlines: while :; do :; done

while : is usually used if you want to do something repeatedly without a special condition attached. You might use continue, break statements within the loop to control it or to move the condition to the end of the loop like a do ... while construct.


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

No, the command in the condition part can be any command(*) . All shell commands have some return value, and the while loop (as well as the if conditional) take return values of zero as "true", and all others as "false". (* or a list of several commands, the last one counts)

As for :, Bash's manual tells clearly what the return status of that is:

: [arguments]
Do nothing beyond expanding arguments and performing redirections. The return status is zero.

The help builtin is even more clear:

 $ help :
 [...]
 No effect; the command does nothing
 Exit Status:
 Always succeeds.