What do you think? Discuss, post comments, or ask questions at the end of this article [More about me]

You might want/need to create a systemd timer.  Systemd timers are pretty much what they sound like - they execute things at specified times - similar to (and an alternative to) cron jobs.

Below we're cover creating a simple systemd timer at the system level.

Guide

We first need a service which will be executed. 

In an actual scenario i used this method to query an internal REST endpoint running on the server and save the returned file in a location (which in docker binds to a location in a container)... sounds confusing but basically I just wanted to generate a file (via a REST call) and save it somewhere.

For out example below though, we're going to do something much simpler: we're just going to create a text file with the current date and then save it an arbitrary location at 0630hrs every day.

Create a systemd service

Let's start by creating our systemd file.  We'll create it in /lib/systemd/system as systemd will then load (but not enable) this service by default:

sudo vim /lib/systemd/system/good-morning.service

I'm using vim here but you can use whatever editor you like (e.g. nano, if you must...).

and copy/paste the following:

[Unit]
Description=Good morning lazybones!

[Service]
Type=simple
ExecStart=/bin/echo "Dear lazybones!, it's a new morning. Love from your system @$(date)" > /var/www/good-morning
Restart=on-failure
RestartSec=30s

The Restart=on-failure and RestartSec=30s aren't really needed here but are handy if we might reasonably expect our ExecStart process to fail (e.g. unclean exit code) and we wanted it to keep trying until it succeeded.

We can this by reloading units in systemd and running our service (can then check that the file was generated):

sudo systemctl daemon-reload
sudo systemctl start good-morning.service

# check output of service
sudo systemctl status good-morning.service

If everything worked (and the file was generated) then we can now create our timer.

Create and enable out systemd timer

With our service created and working we can now create our timer.

We must name the timer the same as the service but with a .timer extension (unless you define the unit service name with the Unit= option).

Similar to the previous step, let's now create the timer in the same location:

sudo vim /lib/systemd/system/good-morning.timer

and copy/paste the following:

[Unit]
Description=Executes the good-morning service every morning.

[Timer]
OnCalendar=*-*-* 06:30:00
Persistent=true

[Install]
WantedBy=timers.target

 The above timer simply executes our previous created service every morning (at 6.30am).  You can read more about the OnCalendar option and the formats that can be used (it's very versatile).

The Persistent option enables the service to trigger if it didn't when it should have previously (e.g because the computer/server was down / off / thrown out the window etc.).

Let's now reload systemd, enable, and start the timer:

sudo systemctl daemon-reload
sudo systemctl enable good-morning.timer
sudo systemctl start good-morning.timer

That's it.  You should now get a nice (rude?) text file created in /var/www every morning at 6.30am.

References

  1. https://www.freedesktop.org/software/systemd/man/systemd.timer.html
  2. https://www.freedesktop.org/software/systemd/man/systemd.time
  3. https://wiki.archlinux.org/index.php/Systemd/Timers