-
Systemd timers are a modern replacement for Cron.
-
Three ways to use timers: systemd-run for one-offs, OnCalendar for cron-like schedules, and event timers for boot/start.
-
Switching is worth it: systemd timers offer better reliability, dependency awareness, and easier logs.
Cron has enjoyed decades of development and widespread use and is still an effective and reliable way to schedule scripts on Unix systems. But it's not the only scheduling utility. In fact, many would argue that it's time we all ditched Cron for systemd timers since they are the superior, more modern way to schedule scripts.
Cron vs. systemd timers: Is it time to ditch Cron?
Cron's history dates back to the early days of Unix development . But don't let its age fool you; as Google Trends shows, cron is still wildly popular. Some might even say cron jobs are 'the most used way to schedule scripts.
I've used it to schedule a backup script , a script that clears my browser cache upon exit, one that deletes old logs, and more. You've probably used it in other fun ways. Even though Cron is still a perfectly acceptable way to schedule scripts, it has a few feature gaps and limitations. That's where systemd timers come in. They were introduced into systemd in 2014 as a 'cron replacement.' They can do everything cron does and then some. Check out this table that compares cron jobs and systemd timers.
Even if you're a die-hard Cron fan, you have to agree that systemd timers have way more going for them. They offer additional features that make them a more robust way to schedule scripts on Unix systems.
3 ways to schedule scripts with systemd timers on Ubuntu
There are three primary ways to run and schedule scripts using systemd timers:
-
Quick one-off script running using systemd-run
-
Script scheduling with OnCalendar timers
-
Event-triggered script scheduling
Quick one-off script running using systemd-run
Use nano or another terminal text editor to copy and save the following script as ~/resource_snapshot.sh, then use the chmod command to make it executable.
Remember to include the shebang (#!/bin/bash) in your script and to make it executable using chmod +x. Failing to do so will cause the systemd service to not work.
Now use the systemd-run command to execute it using a temporary service unit, which is great for running a script without scheduling. After running the script, use systemctl to check its status. It will return a 'not found' status since we've run it as a service that disappears after running, but we can still use journalctl to read the log .
Script scheduling with OnCalendar timers
OnCalendar is the most Cron-like way to schedule scripts on Ubuntu. I'll illustrate by scheduling the resource-usage script. First, use nano to create a systemd service unit file so systemd knows what to run, then copy and paste the configuration into it. For this illustration, I'll run the script once, then exit, but you can use other types like simple, exec, or idle. Also, edit ExecStart to match your path.
The next step is to create a systemd timer unit that specifies when the service should run. I'll use nano for this, but you can use any terminal text editor to copy and paste the configurations. Since I want this script to start automatically, be persistent, and run every day at 3:00 PM, I've defined that in the timer. You can change these configurations to suit your needs; just remember the syntax: * *-*-* *:*:*, which represents DayOfWeek Year-Month-Day Hour:Minute:Second, but you can also use wildcards. Also, remember that you can use the systemd-analyze calendar command to debug timer syntax errors.
After saving the config, I'll reload systemd to make it aware of the service and timer unit files. After that, I can start the timer immediately, enable it to run at system boot, then verify it's active, and use journalctl to read the log file.
Relative or event-triggered script scheduling
Also known as the monotonic pattern, the structure of event-based systemd timers is very much like if-this-then-that because they run relative to specific events, such as system boot time. Let's consider an example where I want my resource snapshot script to run 1 minute after my system boots. Since I already have a service unit file for resource-snapshot.service, I'll reuse that. However, since I now want to schedule the script using a relative trigger, I'll need to create a new timer unit with new configurations.
After saving the new timer unit, I'll reload systemd, enable and start the timer, and verify it.
Besides OnBootSec, you can use relative timer options like OnStartupSec, OnUnitActiveSec, or OnUnitInactiveSec.
As you can see, compared to Cron, systemd timers are the smarter, more reliable way to run and schedule scripts. Even if you're a die-hard Cron fan, it may be time to ditch it for the modern standard.
