25

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?

  • 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 '17 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 '17 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 '17 at 15:28
50

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.