Systemd Timer on Linux: Replace Cron with Scheduling
The Systemd service manager also maintains a task scheduling service that can be used as a replacement for cron. Some distributions no longer even install cron by default, using only systemd-timer on Linux.
Over time, distributions have come to prefer systemd for system maintenance tasks.
Systemd uses time unit files called "Timers" that control the services or events that will be executed by systemd. These files have the extension .timer and usually reside in the /lib/systemd/system directory.
Although using systemd scheduling can be somewhat more complex than cron, there are some advantages:
- Each task has its own time unit, or more than one if necessary;
- Time units can call any unit, whether service, mount, socket, etc;
- Time units can be executed manually;
- Time units can depend on other services or units to be executed, forming a logic for the execution of programs or services;
- Units can be grouped;
- Executed jobs are logged in the systemd journal, which facilitates debugging;
Time units can be of two types:
- Real-time Timers: are triggered by a calendar event, in the same way as cron. The OnCalendar option in the time unit is used to define this type of time unit.
- Monotonic Timers: are triggered after a certain amount of time (in seconds) relative to a specific event. This event can be after the timer service is started (OnActiveSec), after the computer boots (OnBootSec), after the systemd service was started (OnStartupSec), and after a time unit was last active (OnUnitActiveSec).
To create a systemd timer task, it is necessary to create two unit files: one for time and another with the service or command that will be executed. First you can create the time unit:
[Unit]Description=Backup do MySQL[Timer]OnCalendar=*-*-* 03:00:00Unit=backup.service[Install]WantedBy=multi-user.target
This unit should be placed in the /usr/lib/systemd/system/ directory with the name backup.timer. Note that it will execute every day at 3 AM and call the backup.service unit. Now it is necessary to create the service unit that will be executed by the backup.timer unit:
[Unit]Description=Backup do MySQL[Service]Type=simpleExecStart=/var/backup.sh[Install]WantedBy=multi-user.target
This file should also be placed in the /usr/lib/systemd/system/ directory with the name backup.service. Note that this unit will execute the script /var/backup.sh. This script in turn should have "X" execute permission. Once this is done, you must enable the timer unit to run at boot with the "enable" option of the systemctl command:
# systemctl enable backup.timer
And also put it into execution with the "start" option of the systemctl command:
# systemctl start backup.timer
Whenever it is necessary to change the configuration of a unit, it is necessary to restart the systemd service:
# systemctl daemon-reload
To view the time units that are configured, you can use the "list-timers" option of the systemctl command:
# systemctl list-timersNEXT LEFT LAST UNIT ACTIVATES2019-10-19 10h 2019-10-18 backup.timer backup.service
To list all time units, even those that are not active, you can use the "list-timers --all" option:
# systemctl list-timers --allNEXT LEFT LAST UNIT ACTIVATES2019-10-18 8min 2019-10-18 dnf.timer dnf-makecache.service2019-10-19 13h 2019-10-18 tmp.timer tmpfiles-clean.servicen/a n/a n/a read.timer readahead-done.service3 timers listed.
To stop the time unit, you can use the "stop" option of the systemctl command:
# systemctl stop backup.timer
And you can execute the backup.service unit at any time with the command:
# systemctl start backup.service
Transient Time Units
Systemd can also be used to create transient time units that will execute only once on a specific date, without the need to create a service unit.
To do this, we use the systemd-run command.
systemd-run
The options that systemd-run accepts are:
- --on-active=: number of seconds after the timer system became active.
- --on-boot=: number of seconds after the computer started.
- --on-startup=: number of seconds after systemd started.
- --on-unit-active=: number of seconds after a unit became active
- --on-unit-inactive=: number of seconds after a unit became inactive
- --on-calendar=: calendar date for task execution.
Examples:
In this example, the timer will create a file called /tmp/arquivo 30 seconds after it was activated:
# systemd-run --on-active=30 /bin/touch /tmp/arquivoRunning timer as unit run-1642.timer.Will run service as unit run-1642.service.
The timer execution can be viewed in the Systemd Journal with the journalctl command:
# journalctl -b -u run-1642.service-- Logs begin at Tue 2019-04-09 15:46:28 -03Oct 18 16:05:05 systemd[1]: Started /bin/touch /tmp/arquivo.
To execute the updatedb command on a specific date, you can use the "--on-calendar=" option with a date in quotes:
# systemd-run --on-calendar="sun 13:50" updatedbRunning timer as unit run-2948.timer.Will run service as unit run-2948.service.
After creating the time and service unit with systemd-run, you can use the "systemctl list-timers" command to see the timer unit created:
# systemctl list-timersNEXT UNIT ACTIVATES2019-10-20 13:50 run-2948.timer run-2948.service
The content of the unit created by systemd-run can be viewed with the "systemctl cat run-2948" command:
# systemctl cat run-2948[Unit]Description=/bin/updatedb[Service]ExecStart=@/bin/updatedb "/bin/updatedb"
Learn much more about Linux in our online course. You can enroll here. If you already have an account, or want to create one, just log in or create your user here.
Like it? Share
That was just one piece. The course teaches the whole path — from your first command to exam day.