Scheduled jobs with systemd timers


Introduction

This post provides a quick overview of how to set up a scheduled job using systemd. Traditionally cron would be used, however; many Linux distributions now use systemd and some no longer have cron installed by default. The scheduled job that will be configured in this post will be run by the service manager of the local user, as opposed to the system service manager. This post assumes some familiarity with systemd.

systemd unit files

Under systemd, a scheduled job consists of two parts: the timer and the service. The timer dictates when the job should run and the service dictates what the job should run. Both the timer and service are systemd unit files, examples of which are shown below.

~/.config/systemd/user/check_mail.timer

[Unit]
Description=Timer that triggers a job to run that checks for new email

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target

~/.config/systemd/user/check_mail.service

[Unit]
Description=A service that checks for new email

[Service]
ExecStart=~/.local/bin/check_mail

There are a few interesting points to note:

  1. The timer will trigger the service on an hourly basis.
  2. The timer knows which service to run because the service has the same filename: check_mail.
  3. When run, the service will execute a check_mail program that is located in the user's ~/.local/bin directory.
  4. The timer and service unit files are located in the user's local config directory. As mentioned previously, this scheduled job will be run by the service manager of the user, not the system.

Installing the timer

Once the files are configured correctly and in place on the file system the timer can be started by issuing the following commands:

  1. $ systemctl --user daemon-reload

    This will reload the systemd manager configuration, picking up new and changed unit files. This is necessary in order to have systemd recognise the new timer and service files.

  2. $ systemctl --user enable --now checkmail.timer

    This will install the timer by creating a set of symlinks, enabling it to be automatically started at boot time. The --now switch is supplied in order to start the timer without having to reboot.

That's all there is to setting up a systemd timer and service.

Monitoring the timer

It's useful to be able to check what timers are installed, their status, and their logs.

  1. Listing the installed timers:

    $ systemctl --user list-timers

  2. Checking the status of a timer or service:

    $ systemctl --user status checkmail.timer

    $ systemctl --user status checkmail.service

  3. Viewing the logs of a timer or service (the -f switch allows the logs to be tailed):

    $ journalctl -f --user-unit checkmail.timer

    $ journalctl -f --user-unit checkmail.service