Score:3

How to start and stop a systemd service on a timer?

sc flag

While it's relatively straightforward to setup systemd to start a service at a particular time, how can I also make it stop at a different time?

The idea would be to run a service overnight only, and stop it in the morning.

Alessandro Carini avatar
in flag
There is some reason for avoiding the use of crontab?
Artur Meinild avatar
vn flag
@AlessandroCarini there could be several reasons. `systemd` timers have a more flexible configuration than crontab. And this is a perfectly valid question about `systemd`, so no reason to make it about crontab.
Score:3
vn flag

You are correct, that a systemd timer is designed in a way so that it starts a service at a specific time. So to make it stop a service, it's necessary to make a workaround.

Luckily, there are several ways to achieve this.

Option 1: Make Service A conflict with Service B

The first option is to create a oneshot Service B that is in conflict with Service A. The advantage of this method is that it relies solely on systemd unit files, but the disadvantage is that you have to modify Service A (or create drop-in configuration).

First, you need to modify the configuration of Service A, so it conflicts with Service B:

Add this the configuration of A.service:

[Unit]
Conflicts=B.service
...

Then create a B.service that does nothing:

[Unit]
Description=B service description

[Service]
Type=oneshot
ExecStart=/bin/echo ''

This method is taken from this Q&A.

Option 2: Make Service B simply stop Service A

Another option is to create a oneshot Service B that simply runs the command to stop Service A. The advantage of this method is that you don't have to modify Service A, but the disadvantage is that it relies on running systemctl and not solely on systemd unit files.

For this method, you only need to create a B.service, but this time it will run a command:

[Unit]
Description=B service description

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl stop A.service

For both options, you then create a different timer for each of those services. Timer A will now start Service A, and Timer B will later start Service B - effectively stopping Service A.

See this Q&A for more information about setting up systemd services and timers.

Raffa avatar
jp flag
For completeness: [`RuntimeMaxSec=`](https://www.freedesktop.org/software/systemd/man/systemd.service.html#RuntimeMaxSec=) might be set although will report the service as `failed` after termination, but that can only be cosmetic in most cases ... And if that service is used to run a script, then some logic can be implemented within the script to end both as well.
sc flag
Thanks a lot, I've set this up and it looks like it should work. Meanwhile I've also put a [feature request](https://github.com/systemd/systemd/issues/28684) with systemd to simplify this.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.