Linux - Systemd Scheduling and Executing Scripts

I am currently in need of running a script every day at a certain time and what immediately came to my mind was crontab. However, my arch linux does not come with crontab installed by default and their documentation recommends using the already installed systemd-timer.

1) Create a Unit to Execute a Script

First, we need to create a file to execute our script. In a nutshell a unit file contains general sections and properties that applies to all types of unit files and also specific sections and properties for each different unit types. Check the manual for all the available options.

[Unit]
Description=Service to backup server-1.18.1-carpet-2 map.

[Service]
Type=exec
User=minecraft
Group=minecraft
SyslogIdentifier=backup-server-1.18.1-carpet-2
ExecStart= /mineserver/scripts/backup.sh \
          -d sequential \
          -m 2 \
          -c \
          -i /mineserver/server-1.18.1-carpet-2/world \
          -o /mineserver/backups/server-1.18.1-carpet-2 \
          -s mine02 \
          -w tmux \
          -v
/etc/systemd/system/mine02-backup.service

After creating the unit file we need to reload systemd's daemon and check our service status.

systemctl daemon-reload
systemctl status mine02-backup.service
○ mine02-backup.service - Service to backup server-1.18.1-carpet-2 map.
     Loaded: loaded (/etc/systemd/system/mine02-backup.service; static)
     Active: inactive (dead) since Wed 2022-02-02 15:21:00 GMT; 31min ago
TriggeredBy: ● mine02-backup.timer
   Main PID: 87552 (code=exited, status=0/SUCCESS)
        CPU: 40.308s

Feb 02 15:20:21 minecraft systemd[1]: Starting Service to backup server-1.18.1-carpet-2 map....
Feb 02 15:20:21 minecraft systemd[1]: Started Service to backup server-1.18.1-carpet-2 map..
Feb 02 15:20:28 minecraft backup-server-1.18.1-carpet-2[87552]: Starting backup... (/mineserver/backups/server-1.18.1-carpet-2/2022-02>
Feb 02 15:20:28 minecraft backup-server-1.18.1-carpet-2[87559]: tar: Removing leading `/' from member names
Feb 02 15:21:00 minecraft backup-server-1.18.1-carpet-2[87552]: Backup complete! (39 s, 895M/2.7G, 69%)
Feb 02 15:21:00 minecraft backup-server-1.18.1-carpet-2[87552]: Deleted old backup (2022-02-02_15-00-21.tar.gz)
Feb 02 15:21:00 minecraft systemd[1]: mine02-backup.service: Deactivated successfully.
Feb 02 15:21:00 minecraft systemd[1]: mine02-backup.service: Consumed 40.308s CPU time.

Because this service will not run at boot time we do not need to enable it.

2) Create a Timer Unit

Timer units are similar to all other however as the name suggests it is a timer. Check the manual for futher options.

It needs to have the same name as the service unit but ending in .timer instead.

[Unit]
Description=Timer to backup the minecraf MC2 world map every day early in the morning.

[Timer]
OnCalendar=*-*-* 7:10:00 
Persistent=true

[Install]
WantedBy=timers.target
/etc/systemd/system/mine02-backup.timer

Opposite to the service unit, we want our timer to be enabled during boot time. To enable it execute the below:

systemctl enable mine02-backup.timer
Created symlink /etc/systemd/system/timers.target.wants/mine02-backup.timer → /etc/systemd/system/mine02-backup.timer.

And finally, start it.

systemctl start mine02-backup.timer
systemctl status mine02-backup.timer
● mine02-backup.timer - Timer to backup the minecraf MC2 world map every day early in the morning.
     Loaded: loaded (/etc/systemd/system/mine02-backup.timer; enabled; vendor preset: disabled)
     Active: active (waiting) since Wed 2022-02-02 14:19:17 GMT; 2h 36min ago
      Until: Wed 2022-02-02 14:19:17 GMT; 2h 36min ago
    Trigger: Thu 2022-02-03 07:10:00 GMT; 14h left
   Triggers: ● mine02-backup.service

Feb 02 14:19:17 minecraft systemd[1]: Started Timer to backup the minecraf MC2 world map every day early in the morning..

We can use systemd-analyze to create and inspect our calendar events.

systemd-analyze calendar "*-*-* 07:10:00"
Normalized form: *-*-* 07:10:00
    Next elapse: Thu 2022-02-03 07:10:00 GMT
       (in UTC): Thu 2022-02-03 07:10:00 UTC
       From now: 14h left

Resources

systemd - ArchWiki
systemd/Timers - ArchWiki
systemd.time(7) — Arch manual pages