Replacing Cron with SystemD.timers
Like most people, Every year I make some new years resolutions. Unlike most people, my resolutions all tend to revolve around IT. Every year I give myself a “It’s
So what was my “one thing” for 2018? Well, near the tail end of 2017 I made a discovery that I was completely unaware of before…SystemD has a built in timer system, that can act as a replacement for cron. Is it easier? No. Far from it. It’s kind of a pain in the ass…is it better? I think so.
You may ask, “Brandon, what IS better about systemd.timers? Why can’t i just keep using cron?” to that I say this:
First cron is dumb. We’ve all had that cron job that is supposed to run every X hours, and every now and again it will take more than X hours to run…and it ruins your life when cron kicks off a second copy of the job. Systemd tracks the PID of the process it starts when the timer is triggered, and it knows that the job is still running when the time rolls around again.
Second your job gets added in as an easily managable systemd journaled service. You can view the logs from the journal. You can enable/disable it with systemctl, and you can force run it with systemctl as well.
Third You can easily get details of all your jobs running on a system with systemctl. Here is an example output of “systemctl list-timers”
NEXT LEFT LAST PASSED UNIT ACTIVATES Wed 2018-02-07 08:28:58 PST 23h left Tue 2018-02-06 08:28:58 PST 17min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Mon 2018-02-12 00:00:00 PST 5 days left Mon 2018-02-05 00:00:00 PST 1 day 8h ago weekly-clamav.timer weekly-clamav.service
As you can see, you can vie wa list of all the timers you have, when they last ran, when they will next run, and what they do.
So…How do you do it? well, as mentioned before…timers are less convenient than a simple cron entry, it requires two files to be created. We’ll use “weekly-clamav” as an example:
/etc/systemd/system/weekly-clamav.timer
[Unit] Description=Perform ClamAV Scan [Timer] OnCalendar=weekly [Install] WantedBy=timers.target
the .timer file handles the scheduling. This is going to be the ongoing “service” that manages the job. as such this should be enabled, and started in systemd
systemctl start weekly-clamav.timer systemctl enable weekly-clamav.timer
Next comes the .service file
/etc/systemd/system/weekly-clamav.service
[Unit] Description=Perform ClamAV Scan [Service] Type=simple Nice=19 IOSchedulingClass=2 IOSchedulingPriority=7 ExecStart=/etc/system-scripts/clam-scan.sh
this service, when started, will execute /etc/system-scripts/clam-scan.sh. This service should be disabled, and stopped:
systemctl disable weekly-clamav.service systemctl stop weekly-clamav.service
You can start it manually to force run the job, and systemd will stop it when the job completes, otherwise the weekly-clamav.timer will start the service manually on a weekly basis.
And that is all there is to it.