Yesterday I’ve got rid of a to do I had for months in my list: converting my crontab to systemd timers. Once the timers are set they can be controlled via systemctl, log to journald, systemctl –user shows if something failed and systemctl –user list-timers shows a list of your timers, when they ran the last time and when they will run the next time. It is great. But since I am not a pro when it comes to systemd I had a hard time figuring out how I get systemd timers to run for my personal context. For example I am using mutt with isync[footnote]isync is far better than offlineimap. It is faster and uses a less ressources but it is imho harder to configure because it is not as widely used as offlineimap. But the developer is very helpful on the mailing list.[/footnote] and for getting automatically my mails, I run several cron jobs or now timers.

After a lot of googling and try and error, this is my solution. There is probably a way to do it more elegant and more efficient, but this works for me.

In ~/.config/systemd/user you have to create two files per job. One file is the service-file, the other one the timer-file. For example myjob.service and myjob.timer.

myjob.service looks something like this:

[Unit]
Description=This is my job I want to run

[Service]
Type=simple
ExecStart=/home/user/bin/some_shell_script.sh foo bar

[Install]
WantedBy=default.target

myjob.timer looks something like this:

[Unit]
Description=Run my job every 6 minutes
RefuseManualStart=no #I can manually start the timer
RefuseManualStop=no #I can manually stop the timer

[Timer]
Persistent=false #when it is true systemd stores when the timer was last run and when the machine boots up after a long time, it will automatically catch up onto this timer if it should have run in the meantime
OnBootSec=80 #how many seconds after the boot should it run the first time
OnCalendar=*:0/20 #I will explain that later
Unit=myjob.service

[Install]
WantedBy=timers.target

OnCalendar takes different arguments which define when the timer runs. You can do stuff like “hourly” or “weekly” or “*:0/20” will run the timer every twenty minutes. The times that can be used by timers are explained in systemd.time(7).

After you created both files, you should start at first your service to find out, if it will run or fail and you need to debug:

systemctl --user start myjob.service

When it runs succesfully:

systemctl --user start myjob.timer
systemctl --user enable myjob.timer

The man-pages you want to read regarding timers are systemd.timer(5) and systemd.time(7).

This is really a quick and dirty-solution and I bet there is a far more elegant way to solve this, but this way I could convert my complete crontab and it is working.

Here are the sources I used to figure out how to get the stuff to work: