Yes, we're now running our Black Friday Sale. All Access and Pro are 33% off until 2nd December, 2025:
Running Scripts at a X-Second Interval
Last updated: September 20, 2024
1. Introduction
In this tutorial, we see how to run a script after every X-second interval, for example, every 5 seconds. We’ll use four different approaches:
Let’s explore these options in detail.
2. Overview
Automating script execution at regular intervals is a common task for system administrators. Usually, the cron utility is a common practice for scheduling tasks on Linux.
Normally, cron can’t schedule tasks less than one minute long. This is what we intend to solve in this tutorial.
There are many cases where we need to run a script more frequently than every 60 seconds:
- Real-time system resource monitoring, such as CPU and memory usage.
- Collecting data from sensors.
- Monitoring a critical process.
- Checking for new files in a directory.
Also, it’s important to note that running a task more frequently might consume more system resources.
3. Using the sleep Command
The sleep command is a simple command that introduces delays between command executions. It can run scripts at regular intervals when combined with a while loop.
Let’s take a basic example of using sleep:
$ cat myscript.sh
#!/bin/bash
while true; do
> system_monitor.log
# Get the amount of memory in use
mem_usage=$(free -m | awk 'NR==2 {print $3 / $2 * 100}')
# Log the data to a file
echo "Memory Usage at date '+%Y-%m-%d %H:%M:%S': $mem_usage%" > system_monitor.log
sleep 5
done
The above bash script monitors the system’s memory in use and logs it to a file named system_monitor.log every 5 seconds.
Let’s break down the above script:
- while loop: makes an infinite loop that will keep running the script indefinitely
- > system_monitor.log: clears the log file for each run of the script
- mem_usage=: variable that stores the calculated memory usage percentage
- free -m: shows memory usage in megabytes
- awk ‘NR==2 {print $3 / $2 * 100}’: calculates the percentage of used memory ($3) from the total ($2) using the second row (NR==2) of the output
- echo ” Memory Usage….> system_monitor.log: redirects the current used memory percentage to the file system_monitor.log along with the timestamp
- sleep 5: pauses the running script for 5 seconds
Next, let’s run the script:
$ ./myscript
Finally, the above script continuously monitors the system’s memory usage every 5 seconds. It then sends the most recent memory usage percentage to the system_monitor.log file.
Moreover, each iteration overwrites the last log. So only the latest memory usage is kept in the log file.
4. Using cron
cron is a Unix job scheduler that schedules jobs to run at fixed times. Thus, these tasks (cron jobs) run periodically at fixed times, dates, or intervals. However, it’s not designed for less than minute-level granularity.
Let’s try to adjust the cron job scheduling using a script.
First, let’s create a script that shows the memory usage of the system after every 5 seconds:
$ cat memory_usage.sh
#!/bin/sh
for i in $(seq 1 11); do
> system_monitor.log
# Get the memory in use
mem_usage=$(free -m | awk 'NR==2 {print $3 / $2 * 100}')
# Get the time interval in seconds
interval=$((i * 5))
# Put the data into the log file
echo "Memory usage for $interval secs is: $mem_usage%" >> system_monitor.log
# Sleep for 5 seconds
sleep 5
done
mem_usage2=$(free -m | awk 'NR==2 {print $3 / $2 * 100}')
echo "Memory usage for 60 secs is: $mem_usage2%" >> system_monitor.log
exit
The above script is the same as the last one, except for a few changes. Let’s try to understand those changes.
First of all, the script prints intervals between the script execution. For this, it uses the $interval variable.
Secondly, it uses a for loop instead of a while loop for iterations.
Thirdly, the script first logs the system’s memory in use every 5 seconds for 11 iterations (totaling 55 seconds). Then, it logs the memory in use for 55-60 seconds duration.
We’ve used a second variable for storing the memory usage for the last 5 seconds (55-60). This is done to balance the script running time and cron scheduling interval.
Next, let’s add a cron job that runs the script every minute:
$ crontab -e
.
.
.# For example, you can run a backup of all your user accounts
# at 5 a.m. every week ...
* * * * * cd /path/to/script && sh memory_usage.sh
Our job is now in place. The script will update the target file after every 5 seconds.
We can use the watch command to see if the file system_monitor.log is updating:
$ watch less system_monitor.log
Lastly, we can see the memory in use and verify it’s being updated every 5 seconds.
5. Using mcron
mcron is a more flexible alternative to cron. It supports sub-minute time intervals for cron jobs, expressed in seconds. Also, it has more advanced scheduling options. The configuration process is similar to that of cron.
Let’s install the mcron package:
$ sudo apt install mcron
The basic syntax for an mcron job consists of a time scheme and the job to run:
(job TIME-SPEC COMMAND)
Let’s take a task to print the memory utilization:
$ cat memory_usage.sh
#!/bin/sh
> system_monitor.log
# Get the memory in use
mem_usage=$(free -m | awk 'NR==2 {print $3 / $2 * 100}')
# Put the data into the log file
echo "$(date '+%Y-%m-%d %H:%M:%S') - Memory usage: $mem_usage%" >> system_monitor.log
exit
The above script is similar to the last one. However, it doesn’t use any looping system. This time, the iterations will be done using the mcron scheduling.
Also, the memory usage is printed with a timestamp.
Next, we have a Guile script that runs our task after every 5 seconds:
$ cat mcron.guile
(job
'(next-second (range 0 59 5)) "cd /path/to/script && sh memory_usage.sh")
Guile is a Scheme interpreter. The above code first moves to the directory containing the script and then runs the script. Also, the next-second function sets the timing for the script. It runs the script from 0 seconds to 59 seconds with an interval of 5 seconds.
So, let’s run the Guile script:
$ mcron mcron.guile
We can use the watch command to see if the memory changes are updated:
$ watch less system_memory.log
As a result, the changes are written to the file.
mcron is less popular than cron, so it might have less community help.
6. Using a SystemD Timer Unit
SystemD is a system and service manager in many modern Linux distributions. It offers a powerful means for scheduling tasks.
Using timer units, SystemD can handle more complex and precise task scheduling.
Let’s again take the script we used with the case of mcron. First, we create a service unit file:
$ cat /etc/systemd/system/myscript.service
[Unit]
Description=My Script Service
[Service]
WorkingDirectory=/home/user/Documents/Test/
Type=oneshot
ExecStart=/bin/bash /path/to/script/memory_usage.sh
The above file defines a SystemD service called myscript.service.
Here, the Unit section tells the purpose of the service. The service section defines the WorkingDirectory parameter. It sets the working directory for the service.
Similarly, the service type is set as oneshot. This means once the job is completed, the script will exit.
Finally, the ExecStart sets the command that will be executed when the service is started.
Next, let’s create a timer unit file:
$ cat /etc/systemd/system/myscript.timer
[Unit]
Description=Run My Script Every 5 Seconds
[Timer]
OnBootSec=5s
OnUnitActiveSec=5s
AccuracySec=1us
Unit=myscript.service
[Install]
WantedBy=timers.target
The above file defines a SystemD timer. It triggers the execution of the myscript.service every 5 seconds.
Here, the Timer section is the main part of the unit. Let’s break it down:
- OnBootSec=5s: sets a delay after the system boot before the timer is first activated
- OnUnitActiveSec=5s: sets the interval between subsequent activation of the service
- AccuracySec=1us: sets the accuracy of the timer to 1 microsecond to trigger the service
- Unit=myscript.service: sets the name of the service unit that this timer will activate
Now, we need to reload SystemD to take in the new timer and service units:
$ sudo systemctl daemon-reload
In the end, we need to enable and restart the timer service:
$ sudo systemctl enable myscript.timer
$ sudo systemctl start myscript.timer
Let’s see if our script is working as expected using:
$ watch less system_monitor.log
So, as expected, the system_monitor.log file is automatically populated with the new entries after every 5 seconds.
7. Conclusion
In this article, we saw different ways to run a script after every 5 seconds. For quick, temporary solutions, the sleep command offers simplicity and ease of use.
Cron is a reliable, widely supported method for scheduling tasks at intervals of one minute or longer. Further, mcron extends cron’s capabilities with support for sub-minute intervals and more flexible configuration options.
Finally, SystemD timer units offer precise control and integration with modern Linux systems. It has highly accurate timing, down to the microsecond.