paxdiablo
paxdiablo

Reputation: 882118

How do I use systemd to replace cron jobs meant to run every five minutes?

We have an embedded target environment (separate from out host build environment) in which systemd is running but not cron.

We also have a script which, under most systems, I would simply create a cron entry to run it every five minutes.

Now I know how to create a service under systemd but this script is a one-shot that exits after it's done its work. What I'd like to do is have it run immediately on boot (after the syslog.target, of course) then every five minutes thereafter.

After reading up on systemd timers, I created the following service file is /lib/systemd/system/xyzzy.service:

[Unit]
Description=XYZZY
After=syslog.target

[Service]
Type=simple
ExecStart=/usr/bin/xyzzy.dash

and equivalent /lib/systemd/system/xyzzy.timer:

[Unit]
Description=XYZZY scheduler

[Timer]
OnBootSec=0min
OnUnitActiveSec=5min

[Install]
WantedBy=multi-user.target

Unfortunately, when booting the target, the timer does not appear to start since the output of systemctl list-timers --all does not include it. Starting the timer unit manually seems to work okay but this is something that should be run automatically with user intervention.

I would have thought the WantedBy would ensure the timer unit was installed and running and would therefore start the service periodically. However, I've noticed that the multi-user.target.wants directory does not actually have a symbolic link for the timer.

How is this done in systemd?

Upvotes: 0

Views: 2811

Answers (1)

Mark Stosberg
Mark Stosberg

Reputation: 13401

The timer is not active until you actually enable it:

systemctl enable xyzzy.timer

If you want to see how it works before rebooting, you can also start it:

systemctl start xyzzy.timer

In terms of doing that for a separate target environment where you aren't necessarily able to easily run arbitrary commands at boot time (but do presumably control the file system content), you can simply create the same symbolic links (in your development area) that the enable command would do.

For example (assuming SYSROOT identifies the root directory of the target file system):

ln -s ${SYSROOT}/lib/systemd/system/xyzzy.timer
      ${SYSROOT}/lib/systemd/system/multi-user.target.wants/xyzzy.timer 

This will effectively put the timer unit into an enabled state for the multi-user.target, so systemd will start it with that target.


Also, normally your custom files would be stored in /etc/systemd/system/. The equivalent lib directory is intended to host systemd files installed by packages or the OS.

If it's important that your cron job run precisely every 5 minutes, you should check the accuracy because systemd's monotonic timers can slip over time

Upvotes: 1

Related Questions