What's here:

How to Run a Script on a Schedule with systemd Timers

Most Linux administrators know about cron, but modern Linux systems also include another powerful scheduling option: systemd timers. A systemd timer lets you run a script on a schedule using the same management framework you already use for services. That means you can start, stop, enable, disable, inspect, log, and troubleshoot scheduled jobs with familiar systemctl and journalctl commands.

The Basic Pattern

A scheduled systemd job normally has three parts: a script that does the work, a .service unit that runs the script, and a .timer unit that schedules the service.

1. A script that does the work.
2. A .service unit that runs the script.
3. A .timer unit that schedules the service.

Step 1: Create a Script

sudo vi /usr/local/sbin/example-job.sh

Add the following script:

#!/bin/bash

LOGFILE="/var/log/example-job.log"

{
    echo "============================================================"
    echo "Example job started: $(date)"
    echo "Hostname: $(hostname)"
    echo "This is where the scheduled work would happen."
    echo "Example job finished: $(date)"
    echo "============================================================"
    echo
} >> "$LOGFILE"

exit 0

Make the script executable:

sudo chmod 750 /usr/local/sbin/example-job.sh
sudo chown root:root /usr/local/sbin/example-job.sh

Test the script manually before involving systemd:

sudo /usr/local/sbin/example-job.sh
sudo tail -n 20 /var/log/example-job.log

Step 2: Create the systemd Service

sudo vi /etc/systemd/system/example-job.service

Create the following service unit:

[Unit]
Description=Run the example scheduled job

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/example-job.sh

Reload systemd and test the service:

sudo systemctl daemon-reload
sudo systemctl start example-job.service
systemctl status example-job.service
journalctl -u example-job.service -n 50

Step 3: Create the systemd Timer

sudo vi /etc/systemd/system/example-job.timer

Create the timer unit:

[Unit]
Description=Run the example scheduled job once per day

[Timer]
OnCalendar=*-*-* 07:00:00
Persistent=true
Unit=example-job.service

[Install]
WantedBy=timers.target

This timer runs the script once per day at 7:00 AM local server time. Persistent=true means the job will run later if the system was powered off during the scheduled time.

Step 4: Enable and Start the Timer

sudo systemctl daemon-reload
sudo systemctl enable --now example-job.timer

Check the timer and view the next scheduled run:

systemctl status example-job.timer
systemctl list-timers --all | grep example-job

Step 5: Test and Troubleshoot

To manually run the scheduled job immediately:

sudo systemctl start example-job.service

To view logs from the service:

journalctl -u example-job.service -n 100
journalctl -u example-job.service -f

To stop the timer temporarily:

sudo systemctl stop example-job.timer

To disable the timer permanently:

sudo systemctl disable --now example-job.timer

Common OnCalendar Examples

Schedule

OnCalendar Value

Every day at 7:00 AM

*-*-* 07:00:00

Every hour

hourly

Every Monday at 1:00 AM

Mon *-*-* 01:00:00

Every day at midnight

daily

Every 15 minutes

*:0/15

Final Thoughts

systemd timers provide a clean and modern way to schedule recurring jobs on Linux. Unlike cron, timers integrate directly with systemctl and journalctl, making them easier to manage, troubleshoot, and monitor. Once you understand the pattern of script, service, and timer, you can apply it to backups, antivirus scans, maintenance tasks, monitoring scripts, and many other server administration jobs.

References

freedesktop.org. systemd.timer: Timer unit configuration. https://www.freedesktop.org/software/systemd/man/systemd.timer.html 

freedesktop.org. systemd.service: Service unit configuration. https://www.freedesktop.org/software/systemd/man/systemd.service.html

freedesktop.org. systemctl: Control the systemd system and service manager. https://www.freedesktop.org/software/systemd/man/systemctl.html