Repeat a command every x interval of time in terminal?

350,207

Solution 1

You can use watch command, watch is used to run any designated command at regular intervals.

Open Terminal and type:

watch -n x <your command>

change x to be the time in seconds you want.

For more help using the watch command and its options, run man watch or visit this Link.

For example : the following will list, every 60s, on the same Terminal, the contents of the Desktop directory so that you can know if any changes took place:

watch -n 60 ls -l ~/Desktop

Solution 2

You can also use this command in terminal, apart from nux's answer:

while true; do <your_command>; sleep <interval_in_seconds>; done

Example:

while true; do ls; sleep 2; done

This command will print the output of ls at an interval of 2 sec.

Use Ctrl+C to stop the process.

There are few drawbacks of watch:

  • It cannot use any aliased commands.
  • If the output of any command is quite long, scrolling does not work properly.
  • There is some trouble to set the maximum time interval beyond a certain value.
  • watch will interpret ANSI color sequences passing escape characters using -c or --color option. For example output of pygmentize will work but it will fail for ls --color=auto.

In the above circumstances this may appear as a better option.

Solution 3

Just wanted to pitch in to sourav c.'s and nux's answers:

  1. While watch will work perfectly on Ubuntu, you might want to avoid that if you want your "Unix-fu" to be pure. On FreeBSD for example, watch is a command to "snoop on another tty line".

  2. while true; do command; sleep SECONDS; done also has a caveat: your command might be harder to kill using Ctrl+C. You might prefer:

    while sleep SECONDS; do command; done
    

    It's not only shorter, but also easier to interrupt. The caveat is that it will first sleep, then run your command, so you'll need to wait some SECONDS before the first occurrence of the command will happen.

Solution 4

Sounds like the ideal task for the cron daemon which allows for running periodic commands. Run the crontab -e command to start editing your user's cron configuration. Its format is documented in crontab(5). Basically you have five time-related, space-separated fields followed by a command:

The time and date fields are:

       field          allowed values
       -----          --------------
       minute         0-59
       hour           0-23
       day of month   1-31
       month          1-12 (or names, see below)
       day of week    0-7 (0 or 7 is Sunday, or use names)

For example, if you would like to run a Python script on every Tuesday, 11 AM:

0 11 * * 1 python ~/yourscript.py

There are also some special names that replace the time, like @reboot. Very helpful if you need to create a temporary directory. From my crontab (listed with crontab -l):

# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"

Solution 5

You can create your own repeat command doing the following steps; credits here:

First, open your .bash_aliases file:

$ xdg-open ~/.bash-aliases

Second, paste these lines at the bottom of the file and save:

repeat() {
n=$1
shift
while [ $(( n -= 1 )) -ge 0 ]
do
    "$@"
done
}

Third, either close and open again your terminal, or type:

$ source ~/.bash_aliases

Et voilà ! You can now use it like this:

$ repeat 5 echo Hello World !!!

or

$ repeat 5 ./myscript.sh
Share:
350,207

Related videos on Youtube

muru
Author by

muru

Updated on September 18, 2022

Comments

  • muru
    muru over 1 year

    How can I repeat a command every interval of time , so that it will allow me to run commands for checking or monitoring directories ?

    There is no need for a script, i need just a simple command to be executed in terminal.

  • l0b0
    l0b0 about 10 years
    +1 but be careful when using expansions. For example, try the difference between watch -n 1 'echo $COLUMNS' and watch -n 1 echo $COLUMNS when resizing your terminal - the former is expanded every second, but the latter is expanded only once before watch starts.
  • Bruno Pereira
    Bruno Pereira about 10 years
    watch exists for that, this is a bit useless I would say
  • nux
    nux about 10 years
    the user told you , no script , and maybe he dont want to monitor anything
  • X Tian
    X Tian about 10 years
    I didn't tell him to write a script, I suggested that if they are looping inorder to watch for particular filesystem event, then inotifywait is useful, and uses less resources than repeating a command. I often run several commands on a command line eg grep something InALogFile|less is that a script ?
  • nux
    nux about 10 years
    its a good answer , try to edit it to look more simple .
  • sourav c.
    sourav c. about 10 years
    I am not claiming this answer is to be used at first place. watch is good in most cases. That is why I mentioned "apart from nux's answer" at the beginning. But there are few problems with watch for example One can not use any aliased commands with watch. Take for example ll which is aliased to ls -laF but can not be used with watch. Also in case if the output of any command is quite long you will be in trouble in scrolling using watch. In these few special cases this answer may appear a better option.
  • Todd Walton
    Todd Walton about 10 years
    @souravc My version of watch at least allows the -c or --color options for colorized output.
  • sourav c.
    sourav c. about 10 years
    @IstvanChung I was saying without adding this --color option. with --color option watch will interpret ANSI color sequences passing escape characters.for example output of pygmentize but it will fail in case of ls --color=auto. I should have been mentioned that. thanks anyway.
  • zBertok
    zBertok about 10 years
    I'm not a big fan of while [[ true ]]. Sure, it works, but so would while [[ false ]].
  • sourav c.
    sourav c. about 10 years
    @Dennis you can also use while true only without [[]] it will work. but only while false will not. when you put anything inside [[]] it will work. for example [[ foo ]]. It is just giving you an infinite loop.
  • zBertok
    zBertok about 10 years
    Precisely my point. [[ true ]] makes it look it it's doing something it doesn't. That can be confusing to somebody unfamiliar with bash.
  • d33tah
    d33tah about 10 years
    while sleep x is better - it's easier to kill.
  • terdon
    terdon almost 10 years
    Why is this an improvement? You just added an extra, needless, step by saving the command as a variable. The only things this does is i) make it longer to type ii) forces you to use only simple commands, no pipes or redirects etc.
  • yoniLavi
    yoniLavi almost 10 years
    Thanks @XTian, a great command. I also now saw in the man page that you can add -m to continually monitor without a loop.
  • northern-bradley
    northern-bradley over 9 years
    The question asks how to run something periodically in the terminal. cron runs behind the scenes rather than in the terminal
  • Cestarian
    Cestarian almost 9 years
    Problem I have with this solution is that you can't run watch as a process and just leave it running in the background (for example with &disown)
  • Maythux
    Maythux almost 9 years
    Remove the extra variable
  • rinogo
    rinogo over 8 years
    Is there any way to use watch with "history enabled" type command? I love using watch, but sometimes I'd prefer to see a log of previous executions as well, instead of just the last one. And yes, I know I can use scripting (while true) to accomplish this, but using the watch utilitiy is so much cleaner!
  • jmspaggi
    jmspaggi over 8 years
    Replying to myself... If your command takes more than the delay you configure, $DELAY will get a negative value and the sleep command will fail so the script will restart right away. Need to be aware of that.
  • nipponese
    nipponese over 8 years
    @BrunoPereira My problem is that my command has a ( char in a path, and watch fails to parse it correctly even when escaped.
  • Bruno Pereira
    Bruno Pereira over 8 years
    @nipponese then you are not escaping it correctly.
  • Sudip Bhandari
    Sudip Bhandari over 7 years
    this worked for simpler commands but with pipelined commands chaining this didn't work for me.. following was the command I tried =>cat api.log | grep 'calling' | wc -l
  • adelriosantiago
    adelriosantiago about 7 years
    This is a nice alternative and, unlike watch, it keeps the command history.
  • dessert
    dessert over 6 years
    Why exactly does it matter where you put sleep in the while loop? I couldn't find any difference, Ctrl+C broke the loop instantly no matter what.
  • d33tah
    d33tah over 6 years
    @dessert: depends on what you're trying to break out from I guess. Normally, ctrl+c would just kill your command and sleep and only break if you kill true.
  • ssinfod
    ssinfod over 6 years
    there is a small typo in the line xdg-open ~/.bash-aliases. it should be: xdg-open ~/.bash_aliases (ie: underscore)
  • Abhijit Sarkar
    Abhijit Sarkar over 5 years
    -bash: watch: command not found, macOS 10.14.1
  • Jesse Buchanan
    Jesse Buchanan over 4 years
    Another weirdness with watch is that if I resize my terminal window, it runs the command again.
  • bendytree
    bendytree almost 4 years
    brew install watch
  • Kulfy
    Kulfy over 3 years
    ... but there would be no x interval time which question asks.
  • kishore
    kishore over 2 years
    @BrunoPereira watch exists for that, this is a bit useless I would say.. really? Does it work on mac system? I have mac with zsh, it says zsh: command not found: watch. (pls read the question, its about terminal, that exists on Mac as well.