Linux – Methods to repeat a command every X seconds


To totally unlock this section you need to Log-in


A Linux system administrator needs to know, sometimes for specific type of tasks, how to run or repeat a Linux command every X seconds. You may need to run a command repeatedly in a certain period of time. Using simple cron commands, for example, such tasks can be easily completed. But cron is not the only tool that we can use to do that.

watch

In order to use watch command, you will be able to execute a command or program periodically and also shows your output on the screen. So you can see the program output in time. The interval can be easily changed to meet your requirements, and also watch re-runs the command/program every 2 seconds. The interval can be easily changed.

Since using watch command is extremely easy, we can test it by firing up a Linux terminal right away typing, for example, the following command:

watch free -m

After using the above command, our system free memory will be checked and the result of the free command will be updated every two seconds.

In case you need to hide the header, displaying information about update interval, command that is being executed, and the current time, we can use the -t option.

Then, we can use the -n option to change the execution interval to let it specify the interval with which the command will be executed. So, to run a script named script.sh file every 10 seconds, we can do it like this:

watch -n 10 script.sh

So, note that to run the above command, for example, we will need to cd to the directory where the script is located or otherwise specify the full path to that script.

Another quick example that let us to display the file system disk space usage (using df command) every 5 seconds is the following:

$ watch -n 5 df -h

Obviously, we can also include pipes into the command set for the watch command, as shown in the following example (in which we are just asking for sda device):

watch -n 5 'df -h | grep /sda'

Below are listed other watch command useful options:

  -b, --beep             beep if command has a non-zero exit
  -c, --color            interpret ANSI color and style sequences
  -d, --differences[=]
                         highlight changes between updates
  -e, --errexit          exit if command has a non-zero exit
  -g, --chgexit          exit when output from command changes
  -n, --interval   seconds to wait between updates
  -p, --precise          attempt run command in precise intervals
  -t, --no-title         turn off header
  -x, --exec             pass command to exec instead of "sh -c"

 -h, --help     display this help and exit
 -v, --version  output version information and exit

Let's see another example, using the following command:

watch uptime

Note: press CTRL+C to exit the command.

Here, the uptime command will run and display the updated results every 2 seconds by default.

Let's consider now the following common scenario: in Linux, while copying files from one location to others using cp command, the progress of data is not shown. We can use the watch command, to see the progress of data being copied.

cp ubuntu-20.04-desktop-amd64.iso /root/ &  watch -n 0.1 du -s /root/ubuntu-20.04-desktop-amd64.iso

Note: the du is a Linux command used to gain disk usage information quickly and also to track the files and directories which are consuming excessive amount of space on hard disk drive.

Sleep with Loop

Sleep is also used in many useful situations; two of them are often for debugging shell scripts and when combined with for or while loops.

The sleep command can be combined with for or while loop types to repeat specific commands (or scripts) each N seconds (the number doesn't have to be an integer, but it can't be negative, obviously; you can also specify minutes - 1m for example, hours - 1h for example, etc.).

But do not worry if this is the first time you hear about the sleep command, it is used to delay something for a specified amount of time (usually in seconds). In scripts, we can use it to tell your script to run a specific command, then wait for 10 seconds, and then run next command.

Having the above loops, we can tell bash to run a command, sleep for N amount of seconds and then run the command again.

Let’s see an example of a for loop:

for i in {1..10}; do echo -n "This is a test in loop $i "; date ; sleep 5; done

The above one-liner, will run the echo command and display the current date, a total of 10 times, with 5 seconds sleep between each execution.

Also, please consider that you are able to change the echo and date commands with your own commands or script and change the sleep interval per your needs.

while true; do echo -n "This is a test of while loop";date ; sleep 5; done

Until it is either killed or interrupted by the user, the above command will run. It is so useful in case you want to run a command running in the background and you don’t want to count on corn.

Note: When using the above methods, it is highly recommended that you set an interval long enough to give enough time of your command to finish running, before the next execution.

Time Drifting Issue

It's also important to note that, using the above approaches (sleep + while/for loop), time will drift, depending on how long the command we are running takes to complete.

Note: for not-critical activities this kind of behavior could be not a problem, but if we need to be precise about the output, for logging and debugging purposes, for example, this scenario, time drifting, could be a problem.

For example, if you want to run a command every 5 seconds, but that command takes 3 seconds to complete, this will cause the command to run every 8 seconds, instead of every 5 seconds.

A solution for avoiding this time drift, and running the command every X seconds regardless of how long it takes to complete (as long as the command doesn't take more to complete than the sleep time), is to use the following:

while true; do currentTime=$(date +%s); elapsedTime=$((currentTime - lastTime)); if [ $elapsedTime -ge X ]; then ; lastTime=$currentTime; i=0; fi; done

Replace X with the time interval between runs (in seconds), and command with the command thet you want to repeat every X seconds.

The above example show a while loop that stores the current Unix time as currentTime, then it subtracts the last time (lastTime) from the current time, storing it as elapsedTime.

Next it checks if the elapsed time is greater or equal to X and if it is, it runs command (so the command is repeated every X seconds). And finally, it sets the lastTime to be equal to the current time, so the next time it runs it can subtract lastTime from the currentTime, which gives the elapsedTime value.

The following one-liner repeats the echo $(date) every 5 seconds:

while true; do currentTime=$(date +%s); elapsedTime=$((currentTime - lastTime)); if [ $elapsedTime -ge 5 ]; then echo $(date);lastTime=$currentTime; i=0; fi; done

Conclusion

The samples in this tutorial are useful but are not meant to completely replace the cron utility.

Use cron (crond) when you need to run commands periodically even after system reboots (and with no direct user interaction with the system itself, so in full background execution). Use the methods explained in this tutorial for programs/scripts that are meant to run within the current user session.


Summary
Article Name
Linux - Methods to repeat a command every X seconds
Description
A Linux system administrator needs to know, sometimes for specific type of tasks, how to run or repeat a Linux command every X seconds. You may need to run a command repeatedly in a certain period of time. Using simple cron commands, for example, such tasks can be easily completed. But cron is not the only tool that we can use to do that.
Author
Publisher Name
Heelpbook.net