Convert Personal Crontab to Systemd --user schedule

There has been some discussion on the forum (both pro and con) over the future discontinuance of crontab in favor of systemd. A good example of documentation of the details of systemd and creation of a systemd service can be seen at https://linuxhandbook.com/create-systemd-services/ . I am a openSUSE leap 15.6 user and if you look at the current system there are many examples of the use of systemd.

BTRFS
btrfs-balance.service
btrfs-balance.timer
btrfs-defrag.service
btrfs-defrag.timer
btrfs-scrub.service
btrfs-scrub.timer
btrfs-trim.service
btrfs-trim.timer

PODMAN
podman-auto-update.service
podman-auto-update.timer

The downside of the base systemd process is the storage of the components in root-owned spaces as opposed to USERID-owned spaces. Systemd does have a facility to allow and support USERID-owned spaces by using the --user parameter on your systemd invocations. Using --user creates a USERID-space invocation of systemd including a file structure in the user’s own .config space (ie: /home/USERID/.config/systemd/user).

My objective was to replace my USERID crontab with systemd services while making as few changes to script invocations out of my $PATH libraries.

Please enjoy and comment if you wish.

CRONEX:AM:PLE  # A script

#!/bin/bash

# Preparation
PRGNAM=$(basename -- "$0")
WHERE=/tmp/$PRGNAM.log
CPWHERE=/tmp/$PRGNAM.txt
CPDEST=
00echolines                    > $WHERE  # An eyecatcher in the sesults
echo $PRGNAM - $(date +%F_%T) >> $WHERE  # Result title line with date and time

# crontab commands
echo -e "Run CRONEX:AM:PLE" >> $WHERE
echo somecommand            >> $WHERE

# Cleanup
00echolines                   >> $WHERE  # An eyecatcher in the sesults
if safebulktest > $CPWHERE ; then        # Local storage space setup
   CPDEST=~/Bulk/00RAU-Sysd-Daily-Files/$(date +0%u%A)/$PRGNAM
else
   mkdir --parents --verbose ~/ZZ-BU-Bulk/00RAU-Sysd-Daily-Files/$(date +0%u%A) >> $CPWHERE
   CPDEST=~/ZZ-BU-Bulk/00RAU-Sysd-Daily-Files/$(date +0%u%A)/$PRGNAM
fi
cp --archive --update --verbose $WHERE $CPDEST >> $CPWHERE  # Copy the result file in /tmp storage to USERID storage
cat $CPWHERE >> $WHERE

# Pick one of the following by UNCOMMENTING for MAIL notification
#echo "$PRGNAM Complete" | mailx -S sendwait -s "Results From $PRGNAM" USERID@AtHome.Home
#OR
#cat $WHERE | mailx -S sendwait -s "Results From $PRGNAM" USERID@AtHome.Home  # $WHERE MUST NOT contain binary data or mailx will create a second attached file
#OR
#echo "Process results are in $CPDEST" | mailx -S sendwait -a $WHERE -s "Results From $PRGNAM" USERID@AtHome.Home

exit 0



CRONEX:AM:PLE.service

[Unit]
Description="Crontab EX:AM:PLE"

[Service]
Type=oneshot
ExecStart=/home/USERID/.config/systemd/user/CRONEX:AM:PLE  # $PATH is NOT available until the .service starts
                                                           # You MUST tell systemd where this is with full path

[Install]
WantedBy=default.target
#WantedBy=multi-user.target



CRONEX:AM:PLE.timer

[Unit]
Description=Run CRONEX:AM:PLE Script

[Timer]
OnCalendar=*-*-* *:00:00
AccuracySec=1sec

[Install]
WantedBy=basic.target

And an example result file.

================================================================
CRONEX:AM:PLE - 2025-05-17_23:00:00
Run CRONEX:AM:PLE
SomeCommand
================================================================

@FredInAriz Hi it should work fine as your user… Probably worth a read https://documentation.suse.com/smart/systems-management/html/systemd-working-with-timers/index.html

Thank you @malcolmlewis . The scheme does work just fine as I have a daily set of 12 “scripts” that are run performing backups and other maintenance tasks.
I will review the suggested document in detail. Systemd is quite powerful with many features and capabilities.

1 Like