7

I wanted to make my shell script wait infinitely and thought the below code would do it.

#!/bin/bash
while true
do
done

However, the above script reports syntax error.

./Infinite_Loop.sh: line 4: syntax error near unexpected token `done'

./Infinite_Loop.sh: line 4: `done'

Unlike programming languages, why does shell script expect at least one statement in loops?

Community
  • 1
  • 1
JSN
  • 2,035
  • 13
  • 27

4 Answers4

13

Another option is just to set a NOP(no op) which is basically, do nothing.

In bash, the equivalent for a NOP is :.

while true; do
  :
done
criw
  • 587
  • 1
  • 5
  • 15
  • `:` [used to be](https://stackoverflow.com/a/12405621/735926) the syntax for comments in earlier shell versions. – bfontaine Jul 07 '17 at 12:42
9

I wanted to make my shell script wait infinitely

If your system supports it use:

sleep infinity

If your system doesn't support it, use sleep with a large interval:

while :; do sleep 86400; done

Note:

  • Using while : in place of while true may/will remove an unnecessary fork, depending on how true is implemented (built into the shell, or as a stand alone application).

You are trying to implement a busy loop, do not do this.

A busy loop will:

  • Use 100% CPU for no useful purpose
  • Prevent other tasks from getting CPU time
  • Reduce the perceived performance of the whole system
  • Use more power than necessary, especially so on systems that support dynamic frequency scaling

Why is an empty loop invalid in shell script?

Because it is... The format for a while loop in bash is as follows:

while list-1; do list-2; done

If you don't provide list-2, then you don't have a correctly formatted while loop.

As pointed out by others, use a noop (:) or anything else to satisfy list-2.

: is documented as follows:

: [arguments]
    No effect; the command does nothing beyond expanding arguments and performing any
    specified redirections.  A zero exit code is returned.
Attie
  • 6,690
  • 2
  • 24
  • 34
2

It’s not part of Bash’s syntax. The manual tells us that:

The syntax of the while command is:

while test-commands; do consequent-commands; done

In fact, if you dig in the Bash source code you can find how it parses a while loop:

shell_command:  ...
    |   WHILE compound_list DO compound_list DONE

If you check compound_list’s definition you can see it must contains at least one shell instruction; it can’t be empty.

There’s no reason for writing an empty (infinite) loop unless you want to heat up your CPU and drain your battery. That’s probably why Bash disallow empty loops.

As others have stated you can use either true or : (the latter is an alias for the former):

while true; do true; done
while :; do :; done
bfontaine
  • 18,169
  • 13
  • 73
  • 107
  • 1
    Someone might follow-up on this answer with the question "but... why isn't it part of Bash syntax?". The answer is that the original developer of the Bourne shell (likely Stephen Bourne) decided that the grammar for a loop required a body, and didn't include a variant in the grammar rules for there to be a loop without a body because it likely didn't make much sense to write a loop that doesn't actually do anything. So, because the developer didn't write grammar rules to anticipate a loop without a body, the shell doesn't support one. – GuyPaddock Jun 03 '19 at 14:27
1

Use true again, from it's man page: true - do nothing, successfully

while true; do true; done
netizen
  • 1,028
  • 7
  • 19