How to schedule a periodic task with systemd

Last updated on February 25, 2023 by Dan Nanni

On Linux, there are cases where you may want to run certain tasks automatically at regular intervals, for example, database backup, vulnerability scans, disk cleanup, log rotation, filesystem check, etc. There are several ways to set up periodic tasks on Linux. One of the most common way of course is to use the cron system. But did you know that you can also use systemd to schedule a job to run automatically at specific time? Now that systemd has become the standard init system for the majority of Linux distros, maybe it is time to learn how to schedule periodic tasks with systemd and look cool!

Schedule a Periodic Task with systemd

To set up periodic tasks using systemd, you need to create a timer unit and a corresponding service unit. Here are the steps to do so.

Create a new file with the .timer extension in the /etc/systemd/system/ directory. The filename should be in the format of "name.timer". For example, if you want to create a timer for a script called myscript.sh, the filename would be myscript.timer.

In the timer unit file, specify when you want the task to run by adding the "OnCalendar" option under the [Timer] section. For example, to run the task every day at 2:30am, you would use the following line:

OnCalendar=*-*-* 02:30:00

To run it every hour:

OnCalendar=hourly

To run it every Monday at 2:30am:

OnCalendar=Mon *-*-* 02:30:00

To run it every 6 hours:

OnCalendar=*:0/6

To run it at 10am and 6pm every day:

OnCalendar=10:00,18:00

Also specify the service unit that the timer should trigger by adding the "Unit" option under the [Timer] section. I will show you how to create the service unit file later. For example, if the service unit is called myscript.service, you would use the following line:

Unit=myscript.service

The complete myscript.timer file looks like the following.

[Unit]
Description=Run myscript every day at 2:30am

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
Unit=myscript.service

[Install]
WantedBy=timers.target

In the above example, the "OnCalendar" option specifies the schedule, and the "Persistent" option ensures that missed job executions are executed when the system starts up. The "Unit" option points to the service file that should be invoked by the timer. The "[Install]" section specifies that the timer should be started when the timers.target is reached during boot.

Once the .timer file is ready, next create a new file with the .service extension in the /etc/systemd/system/ directory. The filename should be in the format of "name.service". For example, if you want to create a service for the myscript.sh script, the filename would be myscript.service. Remember that this filename name should match with the one specified in the timer unit file mentioned earlier.

In the service unit file, specify the command or script that should be run when the timer triggers by adding the "ExecStart" option under the [Service] section. For example, if the script is located in /usr/local/bin/myscript.sh, you would use the following line:

ExecStart=/usr/local/bin/myscript.sh

The complete myscript.service file looks like the following.

[Unit]
Description=My script

[Service]
Type=simple
User=myuser
ExecStart=/usr/local/bin/myscript.sh
Restart=on-failure

[Install]
WantedBy=default.target

In the above example, the "Type" option specifies that the service is a simple process that is started and stopped as a unit. The "User" option specifies the user account that the script will run under. The "ExecStart" option specifies the path to the script that should be run. The "Restart" option specifies that the service should be restarted if it fails. The "[Install]" section specifies that the service should be started when the default.target is reached during boot.

Finally, enable and start the timer unit by running the following command.

$ sudo systemctl enable myscript.timer
$ sudo systemctl start myscript.timer

The above commands should create a timer unit that runs a service unit periodically, according to the schedule you specified. You can check the status of the timer and service units using the following commands.

$ sudo systemctl status name.timer
$ sudo systemctl status name.service

If you modify the timer or service file later, make sure to reload systemd after that by running the following command:

$ sudo systemd daemon-reload

Hope this help!

Support Xmodulo

This website is made possible by minimal ads and your gracious donation via PayPal or credit card

Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.

Xmodulo © 2023 ‒ AboutWrite for Us ‒ Feed ‒ Powered by DigitalOcean