A systemd timer is a unit configuration file that provides a simple and effective way to schedule tasks on Linux. These timers offer an alternative to cron jobs and are the newer method of triggering jobs at specified times. Timer files, just like service files, are units controlled by systemd. The following guide will demonstrate how to run a simple bash script, at regular intervals, using a systemd timer.
Here are further interesting guides: A brief Introduction to Linux and how to create disk partition in Ubuntu Linux, How to Install Terraform on Linux, How to install AnyDesk on a Linux Machine, How to install Golang on a Linux System, How To Install Google Cloud SDK on a Linux System, and how to install and configure Elasticsearch on Linux.
Why use systemd timers as a task scheduler?
Systemd timers offer the best of both cron and anacron thereby allowing scheduling down to minute granularity. The following are some key reasons to use systemd timers.
- Systemd is a standard on most modern Linux systems and timers are a well-integrated part of it, so there is no need to install another package.
- Systemd distributions use systemd-journald for collecting and logging data. It leverages journalctl for querying the contents of the systemd journal just like any other unit logs. This makes debugging easier.
- Jobs can be run manually simply using systemctl start.
- Jobs can be tested without waiting for the schedule.
- Jobs can have complex dependencies and be set up to depend on other systemd units, meaning, a timer can be triggered relative to when other services were activated or deactivated, on machine boot, etc.
The following prerequisite must be met in order to use systemd timers effectively.
- Root privileges
- Basic systemd knowledge
Setting up a systemd timer
Systemd timers consist of two main configuration files:
- Service files are unit configuration files that define and manage systems processes. They use the .service suffix.
- Timers manage when to run these service files. Timer files end in .timer
Create a test script
First, let’s create a basic bash script to run as an example. We will use the vi editor to do this.
sudo vi /usr/local/bin/test.sh
The script will simply print out the date through an echo command.
Now, create a service file to execute this bash script. We will do this under:
sudo vi /etc/systemd/system/test.service
From the top, we first define the unit marker and provide a simple description of what the unit is doing. Then, we define a service of type simple, which means that the command declared in ExecStart is the main process of the service. ExecStart will run the specified command. Lastly, the service will restart in case of failure. See the manual for all possible options for a service unit file.
The next step is to create a timer file.
sudo vi /etc/systemd/system/test.timer
Again, we have a description to explain what the unit does. With the OnCalendar option, we select the time we want to run the script. In this case, the timer will run everyday at 7 pm. The calendar timing format is quite simple. It is a YYY-MM-DD HH:MM:SS format. However, a particular day can also be specified. For instance, if you want to set the service to run every Monday at 3 am, it would be: Mon *-*-* 03:00:00
A comprehensive list of options for the timer unit file can be found here.
Finally, under install, we specify multi-user.target, which indicates that the service should start at runlevels 3, 4, and 5. This option is only set when a service is enabled with systemctl.
Start and enable the timer
The final step is to start and enable the timer. We do this using systemctl. However, we must do a daemon-reload. This will reload the system files in case any new unit files were created or edited.
sudo systemctl daemon-reload
Then we start the timer. We also enable it, so it’s automatically started on boot. The timer then calls the service when scheduled.
sudo systemctl start test.timer sudo systemctl enable test.timer
To make sure the timer is running, use the following command:
sudo systemctl status test.timer
The output shows us whether the timer is running based on its active status. In this case, the timer is active but waiting, indicating that it’s waiting for the next time it will run. What’s more interesting is the trigger part. This displays the time of the next trigger and how long is left. In this case, in 7 hours. It also shows which service the timer triggers.
Other useful commands
We can find even more information about our timers and services using certain commands. The following command can be used to check if the service was successfully executed:
sudo journalctl -S today -f -u test.service
The result shows when the service last started and the output of the bash script.
Next, the systemd-analyze tool converts a relative calendar time expression into its normalized form. We can use this command to ensure our OnCalender value is accurate, and by picking a date in the future, we can also check when a timer will start next.
systemd-analyze calendar 2022-07-25
Another useful command displays all the timers on a system.
sudo systemctl list-timers --all
Here, we can see all our timers, the services associated with them, and when they will next fire.
It is very easy to get started with systemd timers right out of the box. As demonstrated, with only a few steps, a fully automated scheduling job was created and ready to go. Timers can be created for many different jobs such as updates, backups, disk clean-ups, scripts, and more.
I hope you found this blog post helpful. If you have any questions, please let me know in the comment section.