|Index|Working with systemd Timers
SUSE Linux Enterprise Server for NVIDIA 16.1

Working with systemd Timers

Publication Date: 12 Nov 2026

Automating routine maintenance, such as regular backup scripts or routine tasks, is essential for effective Linux system administration. This article offers a comprehensive guide to systemd timers — a modern, flexible alternative to traditional task scheduling. It covers the full lifecycle of systemd timers, including creation, maintenance, testing and troubleshooting, as well as step-by-step guidance on migrating existing workflows from cron.

Prerequisites:

  • Basic understanding of systemd

1 The systemd timer concept

systemd timer units provide a mechanism for scheduling jobs on Linux. The execution time of these jobs can be based on the time and date or on events.

systemd timer units are identified by the .timer file name extension. Each timer file requires a corresponding service file it controls. In other words, a timer file activates and manages the corresponding service file. systemd timers support the following features:

  • Jobs scheduled using a timer unit can depend on other systemd services. Timer units are treated as regular systemd services, so can be managed with systemctl.

  • Timers can be real-time (being triggered on calendar events) or monotonic (being triggered at a specified time elapsed from a certain starting point).

  • Time units are logged to the system journal, which makes it easier to monitor and troubleshoot them.

  • Timers use the centralized systemd management services.

  • If the system is off during the expected execution time, the timer is executed once the system is running again.

2 Creating a timer

The following example shows how to set up a timer that triggers the helloworld.sh shell script after boot time and repeats its execution every 24 hours relative to its activation time. It also runs Monday to Friday at 10 a.m.

2.1 Hello World example

  1. Create an executable file /usr/local/bin/helloworld.sh with the following content:

    #!/bin/sh
      # This is bash program to display Hello World
      echo " Hello World "

    This is an executable .sh file containing the commands you want systemd to run and manage.

  2. Create the file /etc/systemd/system/helloworld.service with the following content:

    [Unit]
    Description="Hello World script"
    
    [Service]
    ExecStart=/usr/local/bin/helloworld.sh

    This is a systemd service file that tells systemd which application to run.

  3. Create the file /etc/systemd/system/helloworld.timer with the following content:

    [Unit]
    Description="Run helloworld.service 5min after boot and every 24 hours relative to activation time"
    
    [Timer]
    OnBootSec=5min
    OnUnitActiveSec=24h
    OnCalendar=Mon..Fri *-*-* 10:00:00
    Unit=helloworld.service
    
    [Install]
    WantedBy=multi-user.target

    This is the timer file that controls the activation of the respective service file.

  4. Verify that the files you created above contain no errors:

    > systemd-analyze verify /etc/systemd/system/helloworld.*

    If the command returns no output, the files have passed the verification successfully.

  5. Start the timer:

    > sudo systemctl start helloworld.timer

    Activates the timer for the current session only.

  6. Enable the timer to make sure that it is activated on boot:

    > sudo systemctl enable helloworld.timer

2.2 The example explained

Example 1: The service file
[Unit]
Description="Hello World script"1

[Service]
ExecStart=/usr/local/bin/helloworld.sh2

1

A brief description explaining the service file's purpose.

2

The application to execute.

The [Unit] and [Service] sections are the minimum sections required for a service file to work. systemd service files normally contain an [Install] section that determines one or more targets for a service to load. This section is not required in service files for timers, since this information is provided with the timer file. For advanced configuration, refer to Managing systemd targets with systemctl.

Example 2: The timer file
[Unit]
Description="Run helloworld.service 5min after boot and every 24 hours relative to activation time"1

[Timer]
OnBootSec=5min2
OnUnitActiveSec=24h3
OnCalendar=Mon..Fri *-*-* 10:00:004
Unit=helloworld.service5

[Install]
WantedBy=multi-user.target6

1

A brief description explaining the timer file's purpose.

2

Specifies a timer that triggers the service five minutes after the system boot. See Monotonic timers for details.

3

Specifies a timer that triggers the service 24 hours after the service has been activated (that is, the timer triggers the service once a day). See Real-time timer for details.

4

Specifies a timer that triggers the service at fixed points in time (in this example, Monday to Friday at 10 a.m.). See Real-time timer for details.

5

The service file to execute.

6

The systemd target in which the timer gets activated. For more information on systemd targets, refer to Managing systemd targets with systemctl.

3 Managing timers

You can manage timers using the systemctl command.

Starting and stopping timers
> sudo systemctl start TIMER.timer
> sudo systemctl restart TIMER.timer
> sudo systemctl stop TIMER.timer
Enabling and disabling timers
> sudo systemctl enable TIMER.timer
> sudo systemctl disable TIMER.timer
Showing the timer file contents
> sudo systemctl cat TIMER.timer
Checking on a specific timer
> sudo systemctl status TIMER.timer
Example 3: Timer Status
> sudo systemctl status helloworld.timer
● helloworld.timer - "Run helloworld.service 5min after boot and every 24 hours
relative to activation time"1
Loaded: loaded (/etc/systemd/system/helloworld.timer; disabled; vendor preset: disabled)2
Active: active (waiting) since Tue 2022-10-26 18:35:41 CEST; 6s ago3
Trigger: Wed 2022-10-27 18:35:41 CEST; 23h left4
Triggers: ● helloworld.service5
6
Oct 26 18:35:41 neo systemd[1]: Started "Run helloworld.service 5min after boot and every 24 hours relative to activation time".7

1

The timer's file name and description.

2

Lists whether a timer has been successfully parsed and is kept in memory (loaded), shows the full path to the timer file, and shows whether the timer is being started at boot time (enabled) or not (disabled). The first value shows the current system configuration, the second value the vendor preset.

3

Indicates whether the timer is active (waiting to trigger events) or inactive. If active, it also shows the time that has passed since the last activation (6 seconds in this example).

4

Date and time the timer is triggered next.

5

Name of the service file the timer triggers.

6

Optional line pointing to documentation (for example, man pages). If not available, an empty line is shown (as in this example).

7

Latest journal entry created by the timer.

To list all timers available on the system, use systemctl list-timers. The following options are available:

List all active timers:
> sudo systemctl list-timers
List all timers including inactive ones:
> sudo systemctl list-timers --all
List all timers matching a pattern:
> sudo systemctl list-timers PATTERN
> sudo systemctl list-timers --all PATTERN

PATTERN must be a name or a shell globbing expression. The operators *, ?, and [] may be used. Refer to man 7 glob for more information on globbing patterns.

List timers matching a certain state:
> sudo systemctl list-timers --state=STATE

STATE takes the following values: active, failed, load, sub. See man systemctl for details.

Example 4: Listing timers

Running any systemctl list-timers results in a table similar to the one below. In this example, all active timers matching the pattern snapper* are listed:

> sudo systemctl list-timers snapper*
NEXT1                       LEFT2      LAST3                        PASSED4   UNIT5                  ACTIVATES6

-----------------------------------------------------------------------------------------------------------------------------
Tue 2022-10-26 19:00:00 CEST 39min left Tue 2022-10-26 18:00:29 CEST 19min ago snapper-timeline.timer snapper-timeline.service
Wed 2022-10-27 08:33:04 CEST 14h   left Tue 2022-10-26 08:33:04 CEST 9h ago    snapper-cleanup.timer  snapper-cleanup.service

1

The point in time when the timer runs next.

2

The time left till the next timer run.

3

The point in time when the timer ran last.

4

Time elapsed since the last timer run.

5

The name of the timer unit.

6

The name of the service the timer activates.

4 Timer types

systemd supports two types of timers: real-time (based on calendar) and monotonic (based on events). Although timers are normally persistent, systemd also allows to set up transient timers that are only valid for the current session.

Real-time timer

Real-time timers are triggered by calendar events. They are defined using the option OnCalendar.

You can specify when to trigger an event based on date and time. Use the following template:

OnCalendar=DayOfWeek1 Year-Month-Day2 Hour:Minute:Second3

1

Day of week. Possible values are Sun, Mon, Tue, Wed, Thu, Fri, Sat. Leave out to ignore the day of the week.

2

Date. Specify month and day by two digits, year by four digits. Each value can be replaced by the wildcard * to match every occurrence.

3

Time. Specify each value by two digits. Each value can be replaced by the wildcard * to match every occurrence.

Applies to all values: Use two dots to define a continuous range (Mon..Fri). Use a comma to delimit a list of separate values (Mon,Wed,Fri).

Example 5: Real-time timer examples
  • 6 p.m. every Friday:

    OnCalendar=Fri *-*-* 18:00:00
  • 5 a.m. every day:

    OnCalendar=Mon..Sun *-*-* 5:00:00
  • 1 a.m. and 3 a.m. on Sundays and Tuesdays:

    OnCalendar=Tue,Sun *-*-* 01,03:00:00
  • Single date:

    OnCalendar=Mo..Sun 2023-09-23 00:00:01
  • To specify triggers at different times, you can create more than one OnCalendar entry in a single timer file:

    OnCalendar=Mon..Fri *-*-* 10:00
    OnCalendar=Sat,Sun *-*-* 22:00

For a full list of available features and options, refer to man 7 systemd.time that offers additional information on the following topics:

  • shorten the syntax and use abbreviations

  • specify repetitions

  • find specific days in a month (last day of month, last Sunday, etc.)

  • apply time zones

Monotonic timers

Monotonic timers are triggered at a specified time elapsed from a certain event, such as a system boot or system unit activation event. Values are defined as time units (minutes, hours, days, months, years, etc.). The following units are supported: usec, msec, seconds, minutes, hours, days, weeks, months, years. There are several options for defining monotonic timers:

  • OnActiveSec: time after unit activation

    OnActiveSec=50minutes
  • OnBootSec: time after system boot

    OnBootSec=10hours
  • OnStartupSec: time after the service manager is started. For system services, this is almost equal to OnBootSec. Use this for user services where the service manager is started at user login.

    OnStartupSec=5minutes 20seconds
  • OnUnitActiveSec: time after the corresponding service was last activated

    OnUnitActiveSec=10seconds
  • OnUnitInactiveSec: time after the corresponding service was last deactivated

    OnUnitInactiveSec=2hours 15minutes 18 seconds
Transient timers

Transient timers are temporary timers that are only valid for the current session. Using these timers, you can either use an existing service file or start a program directly. Transient timers are invoked by running systemd-run.

The following example runs the helloworld.service unit every two hours:

> sudo systemd-run --on-active="2hours" --unit="helloworld.service"

To run a command directly, use the following syntax. In this example, the script /usr/local/bin/helloworld.sh is called directly:

> sudo systemd-run --on-active="2hours" /usr/local/bin/helloworld.sh

If the command takes parameters, add them separated by space:

> sudo systemd-run --on-active="2hours" /usr/local/bin/helloworld.sh --language=pt_BR

Transient timers can be monotonic or real-time. The following switches are supported and work as described in Monotonic timers:

  • --on-active

  • --on-startup

  • --on-unit-active

  • --on-unit-inactive

  • --on-calendar

For more information, refer to man 1 systemd-run.

5 Testing calendar entries

systemd provides a tool for testing and creating calendar timer entries for real-time timers: systemd-analyze calendar. It accepts the same argument as the OnCalendar entry required to set up real-time timers.

You can concatenate several arguments separated by space. If the term to test is correct, the output shows you when the timer is triggered next (in local time and UTC). It also shows the string in Normalized form, and it is recommended to use that string in the timer file. Consider the following examples:

> systemd-analyze calendar "Tue,Sun *-*-* 01,03:00:00"
Normalized form: Tue,Sun *-*-* 01,03:00:00
Next elapse: Sun 2021-10-31 01:00:00 CEST
(in UTC): Sat 2021-10-30 23:00:00 UTC
From now: 3 days left

> systemd-analyze calendar "Mon..Fri *-*-* 10:00" "Sat,Sun *-*-* 22:00"
Original form: Mon..Fri *-*-* 10:00
Normalized form: Mon..Fri *-*-* 10:00:00
Next elapse: Thu 2021-10-28 10:00:00 CEST
(in UTC): Thu 2021-10-28 08:00:00 UTC
From now: 19h left

Original form: Sat,Sun *-*-* 22:00
Normalized form: Sat,Sun *-*-* 22:00:00
Next elapse: Sat 2021-10-30 22:00:00 CEST
(in UTC): Sat 2021-10-30 20:00:00 UTC
From now: 3 days left

For recurring timers, use the –iterations N switch to list trigger times, then test whether they work as expected. The argument N specifies the number of iterations you would like to test. The following example string triggers every 8 hours (starting at 00:00:00) on Sundays:

> systemd-analyze calendar --iterations 5 "Sun *-*-* 0/08:00:00"
Original form: Sun *-*-* 0/08:00:00
Normalized form: Sun *-*-* 00/8:00:00
Next elapse: Sun 2021-10-31 00:00:00 CEST
(in UTC): Sat 2021-10-30 22:00:00 UTC
From now: 3 days left
Iter. #2: Sun 2021-10-31 08:00:00 CET
(in UTC): Sun 2021-10-31 07:00:00 UTC
From now: 3 days left
Iter. #3: Sun 2021-10-31 16:00:00 CET
(in UTC): Sun 2021-10-31 15:00:00 UTC
From now: 4 days left
Iter. #4: Sun 2021-11-07 00:00:00 CET
(in UTC): Sat 2021-11-06 23:00:00 UTC
From now: 1 week 3 days left
Iter. #5: Sun 2021-11-07 08:00:00 CET
(in UTC): Sun 2021-11-07 07:00:00 UTC
From now: 1 week 3 days left

6 Getting e-mail notifications when a timer fails

systemd does not offer a feature similar to cron's MAILTO. This section describes a workaround to enable e-mail notifications when a timer fails.

To set up e-mail notifications for failing systemd services several components are required:

  1. A correctly configured e-mail server (Postfix, for example) on the system running the service (not covered in this article).

  2. A script that sends an e-mail.

  3. A systemd service running the e-mail script.

  4. A modification of the service file for which the failure notification should be sent (adding an OnFailure option and the e-mail recipients).

6.1 The e-mail script

The script requires the service name as an input parameter. It acquires one or more e-mail addresses from the service environment. This lets you use a single script and failure service for the whole system. Each service file specifies its own recipients for the failure notice.

  1. Create the script /usr/local/bin/send_service_failure_email.sh.

    #!/bin/sh
    
    # Send an alert email when a systemd service fails (via failure_email@.service)
    # Parameter: Service name (via %i from the service file)
    #
    # Email address(es) (comma separated, no spaces) must be configured in
    # the service file as environment ALERT_EMAILS:
    # Environment="ALERT_EMAILS=mail1@DOMAIN,mail2@DOMAIN"
    #
    
    UNIT="$1"
    
    # Fetch the environment variables from the failing unit
    ENV_VARS=$(systemctl show -p Environment --value "$UNIT")
    # Extract the value of ALERT_EMAILS
    EMAILS=\
    $(printf '%s\n' "$ENV_VARS" | tr ' ' '\n' | grep '^ALERT_EMAILS=' | cut -d= -f2)
    
    
    # Set fallback email address
    if [ -z "$EMAILS" ]; then
        EMAILS="root@DOMAIN"
    fi
    
    /usr/sbin/sendmail -t <<EOF
    From: $(hostname)@DOMAIN
    To: $EMAILS
    Subject: [ALERT] Systemd service failure for: $UNIT
    
    The systemd service for $UNIT failed to execute on $(hostname) at $(date).
    
    Check journalctl -u $UNIT for details.
    EOF
  2. Replace DOMAIN with the correct domain name. Also verify that hostname delivers the desired result. If not, replace it with a hard coded string. Finally, consider changing the fallback e-mail address.

  3. Make the script executable:

    > sudo chmod 755 /usr/local/bin/send_service_failure_email.sh

6.2 The systemd service running the e-mail script

To trigger an event on failure, systemd requires a service file to call in such an event.

  1. Create the service file /etc/systemd/system/failure_email@.service.

    [Unit]
    Description=Send email notification on service failure for %i
    
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/send_service_failure_email.sh %i
  2. Verify the service file and fix the reported issues:

    > systemd-analyze verify /etc/systemd/system/failure_email@.service

    If the command returns no output, the file has passed the verification successfully.

  3. Test the procedure. Start the service using the dbus instance for testing. (You can use any other service that is currently running. dbus is used in this example because the service is guaranteed to run on any SUSE installation.)

    > sudo systemctl start failure_email@dbus.service

    If successful, the fallback e-mail address from the send_service_failure_email.sh receives an e-mail with the subject [ALERT] Systemd service failure for: dbus. (This is just a test; there is no problem with the dbus service. You can safely delete the e-mail, and no action is required).

    Additionally, inspect the journal:

    > journalctl -u failure_email@dbus.service

    If the test has passed successfully, proceed with the last step that makes the required changes to your service files.

6.3 Editing service files

  1. To receive an e-mail failure notification from a service, add an OnFailure option to the service file and specify the e-mail recipients.

    [Unit]
    Description="Hello World script"
    OnFailure1=failure-email@2%N.service
    
    [Service]
    Environment3="ALERT_EMAILS=mail1@DOMAIN,mail2@DOMAIN"
    ExecStart=/usr/local/bin/helloworld.sh

    1

    The OnFailure option takes a service as an argument.

    2

    %N specifies the base name of the service file (without the file name suffix) (helloworld in this example). This is equal to the service name and is passed to the script as %i in the failure_email@.service file.

    3

    The Environment option lets you define or set environment variables for the respective service. This parameter defines the variable ALERT_EMAILS and sets its value to the desired e-mail addresses. If you specify more than one e-mail address, use a comma as a separator (no whitespace).

  2. Verify the service file and fix the reported issues:

    > systemd-analyze verify /etc/systemd/system/helloworld.service
  3. You have successfully set up the failure notification for systemd services.

7 Using timers as a regular user

systemd timers can also be used by regular users. It helps you to automate recurring tasks like backups, processing images, or moving data to the cloud.

The same procedures and tasks as for system-wide timers are valid. However, the following differences apply:

  • Timer and service files must be placed in ~/.config/systemd/user/. Note that the ~/.config/systemd/user/ directory is not created by default in Linux. You need to initialize it manually using the mkdir -p ~/.config/systemd/user/ command.

  • All systemctl and journalctl commands must be run with the --user switch. systemd-analyze does not require this option.

    > systemctl --user start helloworld.timer
    > systemctl --user enable helloworld.timer
    > systemctl --user list-timers
    > journalctl --user -u helloworld.*
    > systemd-analyze verify --user helloworld.timer
Important
Important: User timers only run during an active session

As with other systemd services started as a regular user, user timers only run when the user is logged in. Instead, to start user timers at boot time and keep them running after logout, enable lingering for each affected user:

sudo loginctl enable-linger USER

For more information, refer to man 1 loginctl.

Important
Important: Environment variables are not inherited

The systemd user instance does not inherit environment variables set by scripts like ~/.profile or ~/.bashrc. To check the systemd environment, run systemctl --user show-environment.

To import any variables missing in the systemd environment, specify the following command at the end of your ~/.bashrc:

systemctl --user import-environment VARIABLE1 VARIABLE2

8 Migrating from cron to systemd timers

All cron jobs can be migrated to systemd timers. Find instructions and an example here.

  1. Create a service file executing the script. See Example 1, “The service file” for details.

  2. Create a timer file executing the service file. See Example 2, “The timer file” for general instructions.

    1. Convert calendar entries. Time is specified differently in cron and systemd. Use the patterns below as a conversion template:

      Cron:               Minute Hour Day Month DayOfWeek
      systemd: OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second

      To test the converted calendar entry, follow the instructions in Section 5, “Testing calendar entries”.

    2. Convert cron nicknames (@NICK):

      Cron     : systemd timer
      -------- : ----------------------------
      @reboot  : OnBootSec=1s
      @yearly  : OnCalendar=*-01-01 00:00:00
      @annually: OnCalendar=*-01-01 00:00:00
      @monthly : OnCalendar=*-*-01 00:00:00
      @weekly  : OnCalendar=Sun *-*-* 00:00:00
      @daily   : OnCalendar=*-*-* 00:00:00
      @hourly  : OnCalendar=*-*-* *:00:00
    3. Convert variable assignments. The systemd variable assignment must go into the [Service] section. You cannot convert MAILTO this way—refer to the next step for this.

      cron: VARIABLE=VALUE
      systemd: Environment="VARIABLE=VALUE"
    4. Set up e-mail notifications to replace cron's MAILTO feature by following the instructions in Section 6, “Getting e-mail notifications when a timer fails”.

Example 6: cron to systemd timer migration

Here are the crontab entries which call the script helloworld.sh 5 minutes after booting and at 10 o'clock each Monday to Friday:

@reboot sleep 300 && /usr/local/bin/helloworld.sh
0 10 * * * 1-5 /usr/local/bin/helloworld.sh

The systemd service file (helloworld.service) calling the script looks like this:

[Unit]
Description="Hello World script"
[Service]
ExecStart=/usr/local/bin/helloworld.sh

The timer file (helloworld.timer) looks like this:

[Unit]
Description="Run helloworld.service 5min after boot and at 10am every Mon-Fri"
[Timer]
OnBootSec=5min
OnCalendar=Mon..Fri *-*-* 10:00:00
Unit=helloworld.service
[Install]
WantedBy=multi-user.target

9 Troubleshooting and FAQs

Learn how to debug and troubleshoot systemd timers that have failed. Find answers to frequently asked questions on systemd timers.

9.1 Avoiding errors

To avoid errors with systemd timers, make sure to follow these best practices:

  • Verify that the executable you specify in the service with ExecStart runs correctly.

  • Check the syntax of the service and timer files by running systemd-analyze verify FILE.

  • Check execution times of calendar entries by running systemd-analyze calendar CALENDER_ENTRY.

9.2 Event is not triggered

When you activate a timer that contains non-critical errors, systemd silently ignores them. For example:

Example 7: systemd timer file cutout containing a non-fatal error
[Timer]
OnBootSec=5min
OnClendar=Mon..Fri 10:00
Unit=helloworld.service

Line 3 contains a syntax error (OnClendar instead of OnCalendar). Since the [Timer] section contains a second timer entry (OnBoot), the error is not critical and is silently ignored. As a consequence, the Monday to Friday trigger is not executed. The only way to detect the error is to use the command systemd-analyze verify:

#  systemd-analyze verify /etc/systemd/system/helloworld.timer
/etc/systemd/system/helloworld.timer:7: Unknown key name 'OnClendar' in section 'Timer', ignoring.

9.3 Checking the system journal for errors

As with every systemd service, events and actions triggered by timers are logged with the system journal. If a trigger does not behave as expected, check the log messages with journalctl. To filter the journal for relevant information, use the -u switch to specify the systemd timers and service files. Use this option to show the log entries for the timer and the corresponding service file:

sudo journalctl -u  helloworld.timer -u helloworld.service

or shorter (if applicable):

sudo journalctl -u  helloworld.*

journalctl is a tool that supports many options and filters. Please refer to man 1 journalctl for in-depth information. The following options are useful for troubleshooting timers:

  • -b: Only show entries for the current boot.

  • -S today: Only show entries from today.

  • -x: Show help texts alongside the log entry.

  • -f: Start with the most recent entries and continuously print the log as new entries get added. Useful to check triggers that occur in short intervals. Exit with Ctrl–C.

9.4 systemd timer: catching up on missed runs

If a systemd timer was inactive or the system was off during the expected execution time, missed events can optionally be triggered immediately when the timer is activated again. To enable this, add the configuration option Persistent=true to the [Timer] section:

[Timer]
OnCalendar=Mon..Fri 10:00
Persistent=true
Unit=helloworld.service

9.5 How to migrate from cron to systemd timers?

All cron jobs can be migrated to systemd timers. Here are general instructions on migrating a cron job:

  1. Create a service file executing the script. See Example 1, “The service file” for details.

  2. Create a timer file executing the service file. See Example 2, “The timer file” for general instructions.

    1. Convert calendar entries. Time is specified differently in cron and systemd. Use the patterns below as a conversion template:

      Cron:               Minute Hour Day Month DayOfWeek
      systemd: OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second

      To test the converted calendar entry, follow the instructions in Section 5, “Testing calendar entries”.

    2. Convert cron nicknames (@NICK):

      Cron     : systemd timer
      -------- : ----------------------------
      @reboot  : OnBootSec=1s
      @yearly  : OnCalendar=*-01-01 00:00:00
      @annually: OnCalendar=*-01-01 00:00:00
      @monthly : OnCalendar=*-*-01 00:00:00
      @weekly  : OnCalendar=Sun *-*-* 00:00:00
      @daily   : OnCalendar=*-*-* 00:00:00
      @hourly  : OnCalendar=*-*-* *:00:00
    3. Convert variable assignments. The systemd variable assignment must go into the [Service] section. You cannot convert MAILTO this way—refer to the next step for this.

      cron: VARIABLE=VALUE
      systemd: Environment="VARIABLE=VALUE"
    4. Set up e-mail notifications to replace cron's MAILTO feature by following the instructions in Section 6, “Getting e-mail notifications when a timer fails”.

Example 8: cron to systemd timer migration

Here are the crontab entries which call the script helloworld.sh 5 minutes after booting and at 10 o'clock each Monday to Friday:

@reboot sleep 300 && /usr/local/bin/helloworld.sh
0 10 * * * 1-5 /usr/local/bin/helloworld.sh

The systemd service file (helloworld.service) calling the script looks like this:

[Unit]
Description="Hello World script"
[Service]
ExecStart=/usr/local/bin/helloworld.sh

The timer file (helloworld.timer) looks like this:

[Unit]
Description="Run helloworld.service 5min after boot and at 10am every Mon-Fri"
[Timer]
OnBootSec=5min
OnCalendar=Mon..Fri *-*-* 10:00:00
Unit=helloworld.service
[Install]
WantedBy=multi-user.target

10 For more information