Glam Prestige Journal

Bright entertainment trends with youth appeal.

I'm trying to figure out a simple way to keep re-executing a command whenever it finishes, for any reason (error or otherwise).

What would be the best way to approach this?

EDIT: I wasn't clear enough before. I need the next execution to wait until the previous one finishes.

EDIT 2: Almost all answers work great. I mistakenly thought most answers would either fork the process or re-execute it just once, neither of which is wanted.

2

7 Answers

This creates an infinite loop, executing command over and over again.

while :
do command
done
5

The watch command will repeat a command forever with an interval specified:

watch -n0 <command>

Setting -n to zero effectively puts the interval at nothing (I think it is really .1 seconds).

watch also has the added benefits of aligning the output so visual changes can be seen easily, and has a switch to highlight changes from the last run.

Reference: the watch man page:

watch runs command repeatedly, displaying its output (the first screenfull). This allows you to watch the program output change over time. By default, the program is run every 2 seconds; use -n or --interval to specify a different interval.

watch will run until interrupted.

9

A simple solution would be:

yourcommand; !#

; separates commands, allowing for multiple commands in one line (Bash: Lists)

!# tells bash to "repeat everything I have written so far in this line" (Bash: Event-Designators)

3

You can plan ahead during command execution (provided it isn't interactive) and enter !! which will execute the previous command again. This works e.g. during ping -c 5.


You can also define a function in bash:

function repeat { "$@"; "$@"; }

To persist it, store it in ~/.bashrc.

Then, you can run your command like this:

repeat ping -c5 heise.de

If it's a specific command you want to repeatedly execute (and not e.g. any command), you can replace "$@" in that snippet with your actual command, and name the function e.g. repeat_ping instead.


To make it an infinite loop, you can do what @Dennis suggests. I recommend you add a waiting period if you intend to use this in an interactive shell, like this:

function repeat { while 1 ; do "$@" ; sleep 1 ; done; }

Otherwise it's rather inconvenient to abort this infinite loop using Ctrl-Z.

3

Give a while loop a boolean condition such as follows:

#!/bin/bash
while true; do do_something && wait
done

This will execute over and over until bash receives a signal to terminate the process. Usually in the form of ctrl+c.

You can also use the watch command to run a script repeatedly as well. For instance a simple clock in your bash terminal using watch could look like:

$ watch -t -n1 date +%T

The -t option tells watch to not display a title of the process it is running. This gives you a clean output of only the command that is being repeated. The -n1 option tells watch to repeat every n seconds. In this case, -n1 will be intervals of 1 second. Then the date +%T command shows the time at the time of command completion. Doing this command will give you an active clock in your terminal.

And then one more method that isn't in any of the other answers would be an infinite function call.

do_something() { do_something }; do_something && wait

This is essentially the same as the boolean while loop only using recursive function calls.

(edit) For keeping your machine's resources in mind, I have added the && wait so that each time a process is run, the loops will "wait" until that process finishes with exit status 0 before the next iteration. This is useful in an interactive shell script.

9

This is another method I use to repeat a command in bash. This might sound silly to some as it does not involve writing a script and might be known to many. But I think it is worth mentioning as it is quick and beginner-friendly, in the sense that there is not much syntax to remember. I've only tested this in gnome-terminal of Ubuntu and other terminals might not support this.

  1. Enter the command in terminal once.
  2. Select the command including newline character with mouse.
  3. Copy the selection using Ctrl-Insert or using context menu (usually accessed with right click).
  4. Use Shift-Insert to paste as many times as you want to run the command.

You don't have to wait to paste until each command finishes. The pasted commands get into a queue and they execute one after another.

I'm feeling saucy today.

Read from one of the infinite streams and pipe it to xargs

cat /dev/zero | xargs --null echo hello there

If you need to put a little bit of a break in there you will likely need to execute sh

cat /dev/zero | xargs --null sh -c "echo hello there; sleep 3"

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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