28

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?

3
  • 4
    The command : does nothing but always exits with return code 0. So, it is the same was while true (assuming your system has a true executable).
    – John1024
    May 25, 2017 at 6:45
  • @John1024 It returns zero unless the evaluation of its arguments causes an error by, for example, assigning a value to a readonly variable.
    – Kusalananda
    May 25, 2017 at 14:15
  • 3
    @Kusalananda Yes, if the : command is never executed, it won't return 0. That's overly pedantic in my opinion though.
    – hvd
    May 25, 2017 at 15:28

3 Answers 3

52

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

12

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.

12

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.
1
  • s/any command/any sequence of commands/, as Stéphane makes clear. May 26, 2017 at 8:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .