We may frequently find ourselves in situations where we want to run a command periodically to view its progress. A watch command is an amazing tool meant to be used for this exact purpose.
Please read our article on the Linux watch command to know more about it.

In this article, we’ll explain how you may use the while loop in a bash shell to simulate the functionality provided by the watch command.

The syntax is simple as shown below:

while true; do echo "Running <command> at $(date)"; <command>; sleep <interval in sec> ; done

Explanation of the above shell script

  • The true keyword turns the while loop into an infinite loop since the exit status or condition to be checked by the while loop will always literally be true.
  • This is followed by the “; operator” which is useful to concatenating/chaining commands in Linux/Unix.
  • Next, we display the name of the command we’ll be executing and $(date) performs a command substitution for the date command.
  • This is followed by the actual command to be executed.
  • Finally, we have the Linux sleep command where we specify the time in seconds after which the next iteration of the while loop should run and display the output of the command.
  • The done statement closes the while loop.
  • You may terminate the while loop by pressing ctrl+c.

Example:

We’ll now demonstrate a simple example where we are checking the contents of a directory at an interval of every 5 seconds to notice any changes.

[root@linuxnix ~]# while true; do echo "Running ls -ltr /tmp/sahil at $(date)"; ls -ltr /tmp/sahil; sleep 5; done
Running ls -ltr /tmp/sahil at Sun Oct 29 10:56:38 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file3
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file1
Running ls -ltr /tmp/sahil at Sun Oct 29 10:56:43 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file3
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file1
Running ls -ltr /tmp/sahil at Sun Oct 29 10:56:48 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file3
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file1
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
Running ls -ltr /tmp/sahil at Sun Oct 29 10:56:53 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file3
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file1
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
Running ls -ltr /tmp/sahil at Sun Oct 29 10:56:58 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file3
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file1
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
Running ls -ltr /tmp/sahil at Sun Oct 29 10:57:03 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file3
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file1
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file7
Running ls -ltr /tmp/sahil at Sun Oct 29 10:57:08 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file3
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file1
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file7
Running ls -ltr /tmp/sahil at Sun Oct 29 10:57:13 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file3
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file1
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file7
Running ls -ltr /tmp/sahil at Sun Oct 29 10:57:18 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file7

In the above output, we view the contents of the /tmp/sahil directory when we initially start the execution of the while loop.
After that contents that are added  or removed are noticeably displayed in the output when the command executes every 5 seconds.
we continue to receive the output until we press ctrl+c to terminate the while loop.

This type of usage is especially beneficial when you are monitoring file transfers to file copy operations.

if writing a one-liner while loop seems tedious then we’ve also created a little script to make things easier.
Here is the script:

[root@linuxnix ~]# cat repeat.bash
#!/bin/bash

while true
do
echo "executing $1 at $(date)"
$1
sleep $2
done

 

The script takes two arguments. The first argument is the name of the command you’d like to execute. The second argument is the time interval in seconds after which you’d like to execute the command.

Given below is a demonstration.

[root@linuxnix ~]# ./repeat.bash "ls -l /tmp/sahil" 5
executing ls -l /tmp/sahil at Sun Oct 29 11:07:15 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file7
executing ls -l /tmp/sahil at Sun Oct 29 11:07:20 IST 2017
total 0
-rw-r--r--. 1 root root 0 Oct 29 10:55 sahil_file2
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file5
-rw-r--r--. 1 root root 0 Oct 29 10:56 sahil_file7
^C

The script continues to run until we press ctrl+c. Notice that I supplied the first argument i.e. the command to execute in double quotes. This is to prevent bash from interpolating whitespaces between strings as separate arguments. So everything within the double quotes will be treated as one argument which in our case is $1 or the first argument supplied to the script. If we did not place the command in double quotes then bash would consider ls as $1, -l as $2 and so on. You may click here to read our article on positional parameters where we cover them in detail.

I hope this tip has been helpful to you and I thank you for reading this article.

The following two tabs change content below.

Sahil Suri

He started his career in IT in 2011 as a system administrator. He has since worked with HP-UX, Solaris and Linux operating systems along with exposure to high availability and virtualization solutions. He has a keen interest in shell, Python and Perl scripting and is learning the ropes on AWS cloud, DevOps tools, and methodologies. He enjoys sharing the knowledge he's gained over the years with the rest of the community.