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 isync1 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.
~/.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 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
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
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:
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.↩