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- 5replace newlines with semicolons. The same works for for loops.Tom– Tom2009-08-17 16:34:06 +00:00CommentedAug 17, 2009 at 16:34
- 24@Tom: that doesn't always work. after the do, you must have the first command, not a semicolonStefano Borini– Stefano Borini2009-08-17 16:38:22 +00:00CommentedAug 17, 2009 at 16:38
15 Answers15
while true; do foo; sleep 2; doneBy 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; done4 Comments
cmdhist option if you are using bash?while true; do sh /Users/myuser/bin/vpn ; doneIt's also possible to use sleep command in while's condition. Making one-liner looking more clean imho.
while sleep 2; do echo thinking; done2 Comments
while 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 ; ...Colon is always "true":
while :; do foo; sleep 2; done4 Comments
: [arguments] No effect; the command does nothing beyond expanding arguments and performing any specified redirections. A zero exit code is returned.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 questionYou can use semicolons to separate statements:
$ while [ 1 ]; do foo; sleep 2; done1 Comment
You can also make use ofuntil command:
until ((0)); do foo; sleep 2; doneNote 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/urandomUsing afor loop:
for ((;;)); do foo; sleep 2; doneAnother way usinguntil:
until [ ]; do foo; sleep 2; done1 Comment
until ((0)); do foo; sleep 2; done does not seem to work. It continuous infinite.Usingwhile:
while true; do echo 'while'; sleep 2s; doneUsingfor Loop:
for ((;;)); do echo 'forloop'; sleep 2; doneUsingRecursion, (a little bit different than above, keyboard interrupt won't stop it)
list(){ echo 'recursion'; sleep 2; list; } && list;1 Comment
sleep, 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.A very simple infinite loop.. :)
while true ; do continue ; doneFr your question it would be:
while true; do foo ; sleep 2 ; doneComments
For simple process watching usewatch instead
1 Comment
watch -n 1 "echo hi"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 ; done3 Comments
&& 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.sleep, 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.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;2 Comments
foo command exit with code1 when you want the while loop to break. I've updated my answer with an example.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.
Comments
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; done3 Comments
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; doneThis deletes them:
for f in *; do if [ "${f#*.}" == 'jpg' ]; then rm -r $f; fi; doneJust trying to contribute.
2 Comments
ls -1 *.jpg andrm *.jpgYou 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 &"2 Comments
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 )Comments
Explore related questions
See similar questions with these tags.












