Scheduling Tasks#
Linux systems come with a number of tools for scheduling tasks on a system. The traditional way to do this is to use the cron
daemon for persistant scheduled jobs or the at
command for non-persistant jobs. The new alternative is to use systemd timers as it is more flexible and more reliable.
Scheduled commands with cron#
Cron is a system for scheduling tasks to be run periodically with a precission of one minute. Multiple implementations are available, but most Linux distributions use the anacron implementation. The name is derived from the name of the greek god Cronos, the god of time.
Using cron itself is simple, but defining the tasks is a bit more involved as you need to figure out the correct scheduling syntax. Let start with option -l
to list all available tasks that are defined for the current user.
$ crontab -l
no crontab for user01
With the option -e
you can edit the cron file as cron makes a copy of the crontab file and lets you edit it via the editor specified in the EDITOR
environment variable or specified as the system default as a fallback.
$ crontab -e
Warning
The option -r
will remove all tasks from the crontab file without prompting for confirmation. Some users confuse this with the -e
option which will edit the crontab file or to view the crontab file in read-only mode.
Removing all tasks from the crontab file can be done with the option -r
.
$ crontab -r
All actions are performed on the crontab file for the current user, but with the following option -u <user>
you can also perform them on the crontab file for another user.
# crontab -u user01 -l
Beside the crontab files per user in /var/spool/cron there is also a cron file for the system cron daemon in /etc/crontab and a cron file for the root user in /etc/cron.d. Taking a closer look at /etc/crontab you can see that the system cron daemon is using the cron file for the root user and can run commands under a different user.
$ cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
Crontab settings per user are located in /var/spool/cron and are similar to the crontab file for the system cron daemon, but without the option to switch to a different user. For all these values you can combine them as single value, a list of values or a range of values, but also divide them to get a matching schedule. Some examples are listed in the table below.
Job definition |
Description |
---|---|
|
Every Friday (5) the is on April (4) 3th at 2:01am |
|
Every day at 4:30am |
|
Every day at 4:30am, 5:30am and 6:30am |
|
Every day at 4:30am, 6:30am, 8:30am |
|
Every day at 4:30am, 6:30am and 8:30am |
|
Every workday during an even month at 15:00 and 20:00 |
|
Every 10 minutes between 8am and 5pm and between 10pm and 11pm |
Scheduled commands with at#
at [-V] [-q queue] [-f file] [-mMlv] timespec...
at [-V] [-q queue] [-f file] [-mMkv] [-t time]
at -c job [job...]
atq [-V] [-q queue]
at [-rd] job [job...]
atrm [-V] job [job...]
batch
at -b
Systemd timers#
Systemd Timers
# systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2021-11-17 02:00:00 CET 15s left Wed 2021-11-17 01:50:34 CET 9min ago sysstat-collect.timer sysstat-collect.service
Wed 2021-11-17 03:19:18 CET 1h 19min left Wed 2021-11-17 01:22:46 CET 36min ago dnf-makecache.timer dnf-makecache.service
Wed 2021-11-17 21:30:46 CET 19h left Tue 2021-11-16 11:17:42 CET 14h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Thu 2021-11-18 00:00:00 CET 22h left Wed 2021-11-17 00:45:27 CET 1h 14min ago logrotate.timer logrotate.service
Thu 2021-11-18 00:00:00 CET 22h left Wed 2021-11-17 00:45:27 CET 1h 14min ago mlocate-updatedb.timer mlocate-updatedb.service
Thu 2021-11-18 00:00:00 CET 22h left Wed 2021-11-17 00:45:27 CET 1h 14min ago unbound-anchor.timer unbound-anchor.service
Thu 2021-11-18 00:07:00 CET 22h left Wed 2021-11-17 00:45:27 CET 1h 14min ago sysstat-summary.timer sysstat-summary.service
Mon 2021-11-22 01:07:18 CET 4 days left Mon 2021-11-15 01:00:34 CET 2 days ago fstrim.timer fstrim.service
n/a n/a Mon 2021-11-15 00:00:35 CET 2 days ago rdiff-backup.timer rdiff-backup.target
9 timers listed.
Pass --all to see loaded but inactive timers, too
$ systemctl --user stop schedule-test.timer
$ systemctl --user disable schedule-test.timer
$ systemctl --user stop schedule-test.service
$ systemctl --user disable schedule-test.service
$ systemctl --user daemon-reload
$ systemctl --user reset-failed
[Unit]
Description=Schedule a message every 1 minute
RefuseManualStart=no # Allow manual starts
RefuseManualStop=no # Allow manual stops
[Timer]
#Execute job if it missed a run due to machine being off
Persistent=true
#Run 120 seconds after boot for the first time
OnBootSec=120
#Run every 1 minute thereafter
OnUnitActiveSec=60
#File describing job to execute
Unit=schedule-test.service
[Install]
WantedBy=timers.target
Transient timer units#
Like
# systemd-run --on-active=30 /bin/touch /tmp/foo
Execute
# systemd-run --on-active="1h 5m" --unit app.service