903

I am having trouble coming up with the right combination of semicolons and/or braces. I'd like to do this, but as a one-liner from the command line:

while [ 1 ]do    foo    sleep 2done
oguz ismail's user avatar
oguz ismail
51.8k16 gold badges64 silver badges83 bronze badges
askedAug 17, 2009 at 16:31
Brian Deacon's user avatar
2
  • 5
    replace newlines with semicolons. The same works for for loops.CommentedAug 17, 2009 at 16:34
  • 24
    @Tom: that doesn't always work. after the do, you must have the first command, not a semicolonCommentedAug 17, 2009 at 16:38

15 Answers15

1687
while true; do foo; sleep 2; done

By the way, if you type it as a multiline (as you are showing) at the command prompt and then call the history with arrow up, you will get it on a single line, correctly punctuated.

$ while true> do>    echo "hello">    sleep 2> donehellohellohello^C$ <arrow up> while true; do    echo "hello";    sleep 2; done
answeredAug 17, 2009 at 16:32
Stefano Borini's user avatar
Sign up to request clarification or add additional context in comments.

4 Comments

"if you type it as a multiline (as you are showing) at the command prompt and then call the history with arrow up, you will get it on a single line, correctly punctuated." was not true for me.
@VincentScheib, checkcmdhist option if you are using bash?
Excellent! Works perfectly on Mavericks (Mac OS-X 10.9) and allows me to keep a vpn running. Openconnect disconnects after a few hours with a bad cookie error. So I put the openconnect command in a shell script, sudo su to become root, and use this cmd line:while true; do sh /Users/myuser/bin/vpn ; done
Worked for me in bash. Just copy paste the script (4 lines), press enter. Press Ctrl+C to exit. Then press up arrow.
233

It's also possible to use sleep command in while's condition. Making one-liner looking more clean imho.

while sleep 2; do echo thinking; done
answeredNov 2, 2012 at 10:53
Anssi's user avatar

2 Comments

Well this does more than just changing the syntax - it will execute the commandafter the sleep. In the previous answer, the command is executed right away. Just something to note.
@DanGordonwhile echo thinking ; do sleep 2 ; done Of course if the [while] command fails, the loop exits, so you would have towhile echo thinking || true ; do sleep 2 ; done but then you are back towhile true ; ...
100

Colon is always "true":

while :; do foo; sleep 2; done
answeredNov 6, 2012 at 13:35
ajaaskel's user avatar

4 Comments

why is colon always true?
@Pineapple Under the Sea: From the bash man page: (in section SHELL BUILTIN COMMANDS): [arguments] No effect; the command does nothing beyond expanding arguments and performing any specified redirections. A zero exit code is returned.
this syntax is recommended as : is part of shell itself i.e. : is a shell builtin command.
@avner: recommended by whom?true is a builtin indash andbash as well. And while posix requirestrue only as executable they write: "even though the shell special built-in : provides similar functionality, because *true``* is widely used in historical scripts and *is less cryptic to novice script readers*. ( IEEE Std 1003.1-2001). See alsothis question
47

You can use semicolons to separate statements:

$ while [ 1 ]; do foo; sleep 2; done
answeredAug 17, 2009 at 16:32
mipadi's user avatar

1 Comment

I like this answer because it explains when and why ; (semicolon) is required.
40

You can also make use ofuntil command:

until ((0)); do foo; sleep 2; done

Note that in contrast towhile,until would execute the commands inside the loop as long as the test condition has an exit status which is not zero.


Using awhile loop:

while read i; do foo; sleep 2; done < /dev/urandom

Using afor loop:

for ((;;)); do foo; sleep 2; done

Another way usinguntil:

until [ ]; do foo; sleep 2; done
answeredAug 25, 2013 at 12:49
devnull's user avatar

1 Comment

Theuntil ((0)); do foo; sleep 2; done does not seem to work. It continuous infinite.
36

Usingwhile:

while true; do echo 'while'; sleep 2s; done

Usingfor Loop:

for ((;;)); do echo 'forloop'; sleep 2; done

UsingRecursion, (a little bit different than above, keyboard interrupt won't stop it)

list(){ echo 'recursion'; sleep 2; list; } && list;
answeredMay 26, 2019 at 4:25
Muhammad Soliman's user avatar

1 Comment

Careful using units insleep, likesleep 1h. In my zsh, it ignores the unith and runs my command every 1 second. Do a quickman sleep to see what your environment'ssleep command supports first. May save you a headache.
18

A very simple infinite loop.. :)

while true ; do continue ; done

Fr your question it would be:

while true; do foo ; sleep 2 ; done
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredJul 9, 2015 at 5:44
Mack's user avatar

Comments

12

For simple process watching usewatch instead

user000001's user avatar
user000001
33.7k14 gold badges86 silver badges113 bronze badges
answeredDec 14, 2016 at 11:35
Christian Schwarz's user avatar

1 Comment

watch -n 1 "echo hi"
9

I like to use the semicolons only for the WHILE statement,and the && operator to make the loop do more than one thing...

So I always do it like this

while true ; do echo Launching Spaceship into orbit && sleep 5s && /usr/bin/launch-mechanism && echo Launching in T-5 && sleep 1s && echo T-4 && sleep 1s && echo T-3 && sleep 1s && echo T-2 && sleep 1s && echo T-1 && sleep 1s && echo liftoff ; done
DanielGibbs's user avatar
DanielGibbs
10.3k13 gold badges80 silver badges126 bronze badges
answeredJan 29, 2011 at 10:43
Thomas's user avatar

3 Comments

Well, the use of&& in the loop is the same as any other time really isn't it. Do you need the second thing to happen only if the first happens, then use&& else; suffices. Really, you want to keep the contents of that loop short and simple, ideally just one command, so a function or a script.
Careful using units insleep, likesleep 1h. In my zsh, it ignores the unith and runs my command every 1 second. Do a quickman sleep to see what your environment'ssleep command supports first. May save you a headache.
Thank you for this. I was looking for the correct way of running more than one thing in the 'do'
8

If you want the while loop to stop after some condition, and yourfoo command returns non-zero when this condition is met then you can get the loop to break like this:

while foo; do echo 'sleeping...'; sleep 5; done;

For example, if thefoo command is deleting things in batches, and it returns 1 when there is nothing left to delete.

This works well if you have a custom script that needs to run a command many times until some condition. You write the script to exit with1 when the condition is met and exit with0 when it should be run again.

For example, say you have a python scriptbatch_update.py which updates 100 rows in a database and returns0 if there are more to update and1 if there are no more. The the following command will allow you to update rows 100 at a time with sleeping for 5 seconds between updates:

while batch_update.py; do echo 'sleeping...'; sleep 5; done;
answeredMay 16, 2017 at 6:50
Yep_It's_Me's user avatar

2 Comments

and how would you exit?
You make thefoo command exit with code1 when you want the while loop to break. I've updated my answer with an example.
7

You don't even need to usedo anddone. For infinite loops I find it more readable to usefor with curly brackets. For example:

for ((;;)) { date ; sleep 1 ; }

This works inbash andzsh. Doesn't work insh.

answeredNov 25, 2020 at 10:26
Victor Yarema's user avatar

Comments

3

You can try this too WARNING: this you should not do but since the question is asking for infinite loop with no end...this is how you could do it.

while [[ 0 -ne 1 ]]; do echo "it's looping";   sleep 2; done
answeredFeb 7, 2017 at 20:47
grepit's user avatar

3 Comments

Why would you even do that?
because Brian Deacon which posted the question wanted like an infinte loop. It's more than one way to skin a cat that's all
Why should you not?
2

If I can give two practical examples (with a bit of "emotion").

This writes the name of all files ended with ".jpg" in the folder "img":

for f in *; do if [ "${f#*.}" == 'jpg' ]; then echo $f; fi; done

This deletes them:

for f in *; do if [ "${f#*.}" == 'jpg' ]; then rm -r $f; fi; done

Just trying to contribute.

answeredJul 2, 2011 at 16:32
Roger's user avatar

2 Comments

@JKnight - for these examples, wouldn't you just dols -1 *.jpg andrm *.jpg
Both are not infinite loops and not while loops.
2

You can also put that loop in the background (e.g. when you need to disconnect from a remote machine)

nohup bash -c "while true; do aws s3 sync xml s3://bucket-name/xml --profile=s3-profile-name; sleep 3600; done &"
answeredJun 15, 2021 at 18:57
michal-michalak's user avatar

2 Comments

I've always tried to avoid this for the (bad?) reason that your editor may not highlight the string context as program sytnax.
I use this structure: nohup bash -c "while true; do COMMAND; sleep 3600; done" > MY.LOG &
0

inbash 5 (or perhaps even earlier), you can also reverse the role of the: by running everything in the loop criteria but using: in the loop body instead :

while ( gdate +"%c ( %s.%-N )" && sleep 0.71  ) do :; done  # discards side-effects      while { gdate +"%c ( %s.%-N )" && sleep 0.71; } do :; done  # no sub-shell needed

+ gdate '+%c ( %s.%-N )'Sun Apr 30 12:38:25 2023 ( 1682872705.498728 )+ sleep 0.71+ :+ gdate '+%c ( %s.%-N )'Sun Apr 30 12:38:26 2023 ( 1682872706.218152 )+ sleep 0.71...

meanwhilezsh is even more forgiving, and willing to loop even without the:

while; do gdate +'%c ( %s.%-N )' && sleep 0.31 ; doneSun Apr 30 12:46:09 2023 ( 1682873169.469092 )Sun Apr 30 12:46:09 2023 ( 1682873169.789560 )Sun Apr 30 12:46:10 2023 ( 1682873170.105635 )Sun Apr 30 12:46:10 2023 ( 1682873170.424766 )
answeredApr 30, 2023 at 16:51
RARE Kpop Manifesto's user avatar

Comments

Protected question. To answer this question, you need to have at least 10 reputation on this site (not counting theassociation bonus). The reputation requirement helps protect this question from spam and non-answer activity.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.