In this blog we are going to learn how and why to use systemd timers instead of cronjobs to schedule our routine(repititve) scripts. Before we start let’s get to know more about what exactly systemd is.
Systemd
systemd is a software suite that provides an array of system components for Linux operating systems.
Systemd provides a standard process for controlling what programs run when a Linux system boots up.
It was created by Red Hat’s Lennart Poettering and Kay Sievers. It does more than start the core programs running. It also starts a journal of system activity, the network stack, a cron-style job scheduler, user logins, and many other jobs.
Systemd timers
So a part of this systmed suite is its timers. Which are and can be used as a replacement for cron jobs. You would ask why? Here are some of the reasons -
- Checking what your cron job really does can be kind of a mess, but all systemd timer events are carefully logged in systemd journal like the other systemd units based on the event that makes things much easier.
- Easily enable/disable the whole thing with:
1systemctl enable/disable
and kill all the job’s children with:
1systemctl start/stop
- Systemd timers can be scheduled with calenders and monotonic times, which can be really useful in case of different timezones.
- systemd time events are more meaningful, for those recurring ones or even those that should occur once, here is an example from the document:
1Sat,Thu,Mon-Wed,Sat-Sun → Mon-Thu,Sat,Sun *-*-*00:00:002 Mon,Sun 12-*-* 2,1:23 → Mon,Sun 2012-*-* 01,02:23:003 Wed *-1 → Wed *-*-01 00:00:004 Wed-Wed,Wed *-1 → Wed *-*-01 00:00:005 Wed, 17:48 → Wed *-*-* 17:48:00
There are many more but instead of going to them I would like to know explain how to set a systemd timer for your process/job. Also this link speaks for itself https://wiki.archlinux.org/title/Systemd/Timers#As_a_cron_replacement.
How to set a systemd timer
So let there be a file named as backup.sh which you want to run at a certain time every week. And the content of that bash file are as follows.
backup.sh
1#!/usr/bin/env bash23echo "I'm just a placeholder for backup" > /tmp/backup_logs.txt
Copy the script to /usr/bin and make it executable:
1sudo cp backup.sh /usr/bin/backup.sh2sudo chmod +x /usr/bin/backup.sh
In systemd world everything has to be a UNIT. SO what happens is first you create a systemd service and then you create a systemd timer calling that service according to the timer configuration.
Now both systemd timers and systemd service are UNITS.
So let’s just create a systemd service from the bash file above. Just create this file under this directory
/etc/systemd/system/
You would need root priviledges to create that(sudo).
backup.service
1[Unit]2Description=Runs my demo backup sh script34[Service]5ExecStart=/usr/bin/backup/backup.sh #Location of the bash file you want to run
Now you just have to create the timer systemd UNIT and start the timer. The only important thing in a timer UNIT file is the [Timer]
section with OnCalendar
parameter.
It takes the arguement for when a timer needs to be run and how frequently just like we have * * * * *
in cron
.
To understand the OnCalendar format here is a small guide.
1DayOfWeek Year-Month-Day Hour:Minute:Second
In the below example the service is run the first four days of each month at 12:00 PM, but only if that day is a Monday or a Tuesday.
1OnCalendar=Mon,Tue *-*-01..04 12:00:00
Now let’s write our timer UNIT file. Inside the same directory /etc/systemd/system/
. Root priviledges would be needed again
backup.timer
1[Unit]2Description=My backup job timer34[Timer]5OnCalendar=*-*-* 4:00:00 # Run at 4 am Everyday6Unit=backup.service #Linking our timer with the service created above.78[Install]9WantedBy=multi-user.target
So after creating this timer UNIT file we just have to enable
it. What enabling does is it ensure your timer will start whenever the system boots up.
You can enable the service unit by command.
1systemctl enable backup.timer
Voila. Your systemd timer is now active you can see it under the output of the list-timers
command as follows.
1systemctl list-timers2>3NEXT LEFT LAST PASSED UNIT ACTIVATES4Thu 2014-07-10 19:37:03 CEST 11h left Wed 2014-07-09 19:37:03 CEST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service5Fri 2014-07-11 00:00:00 CEST 15h left Thu 2014-07-10 00:00:13 CEST 8h ago logrotate.timer logrotate.service
Well there are many configurations that I skipped over here just to explain you the bare minimum needed to have a systemd timer. You can read more configurations here - https://wiki.archlinux.org/title/Systemd/Timers
If you like my blog do subscribe to my newsletter :).
So that is it folks. That is all we have for this tutorial if you want I have setup all this code in a github repo for you. Over here -