185

When you look at how infinite loops should be implemented, you mostly see this approach:

while :
do
  # loop infinitely
done

But I just don't understand the use of : here. Wouldn't it be better to use:

while true
do
  # loop infinitely
done

?

doubleDown
  • 8,048
  • 1
  • 32
  • 48
helpermethod
  • 59,493
  • 71
  • 188
  • 276

2 Answers2

118

from manual:

: [arguments] No effect; the command does nothing beyond expanding arguments and performing any specified redirections. A zero exit code is returned.

As this returns always zero therefore is is similar to be used as true

Check out this answer: What Is the Purpose of the `:' (colon) GNU Bash Builtin?

Community
  • 1
  • 1
phoxis
  • 60,131
  • 14
  • 81
  • 117
41

The colon is a built-in command that does nothing, but returns 0 (success). Thus, it's shorter (and faster) than calling an actual command to do the same thing.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 3
    It's true. `i=0; time while true; do ((i++>100000)) && break; done` takes slightly longer than the colon version. – Dennis Williamson May 29 '12 at 12:50
  • 15
    The difference has nothing to do with commands vs builtins, as they're both builtin. It's purely the additional number of characters bash is dealing with. `while : some gibberish`, still just using `:`, is slower than `true`. Compare this to an external command, like `while /bin/true`, which is literally a hundred times slower. – that other guy Jul 11 '13 at 02:38
  • 3
    I found this question after a red herring due to differences between `while true` and `while 1` - it turns out `1` is aliased to `cd -` which was obviously passing but printing `~` (my cwd at the time.) One caveat with `:` I noticed after trying this out: the usual rules apply to `:`, so you need to end it with a semicolon (or a line break in cases like this one, where you have an unclosed block.) So, for a one-liner, you would write `while :; do ...; done` as opposed to `while :\n do ...\n done`. Really this is hardly a caveat. – John P Feb 18 '18 at 21:25
  • @thatotherguy, almost all of my in-depth knowledge is about compiled languages - does the interpreter really re-parse everything as if it were seeing it for the first time? I would have thought that at the very least, aliases like `:` would be replaced the first time it was encountered. Is the anticipated scenario something like an alias or path changing in the middle of execution? I would have expected `while $(echo true) ...` to defer but never `while /bin/true` -- if `/bin/true` were found to be missing, it would fail without the need for reinterpretation. – John P Feb 18 '18 at 21:33