1

I'm following a tutorial which teaches RedHat and I'm trying to learn how to execute events with systemd. I created the following service

[Unit]
Description=Script2 Logged-In Users

[Service]
Type=simple
ExecStart=/root/Documents/Scripts/script2

[Install]
WantedBy=muti-user.target

which references the following script

#!/bin/bash

echo "Users logged in as of $(date)" >> ~/Documents/UserFiles/useractivity.txt
who >> ~/Documents/UserFiles/useractivity.txt

The script runs successfully when I execute independently, but when I attempt to run it through the timer, it only runs after I start it. Here;s the timer file

[Unit]
Description=Execute Script2 every 10 seconds

[Timer]
#OnBootSec=10min (run script 10 mins after boot)
#OnCalendar=Mon 2015-*-1 10:00:00 (run script at 10am on 1st day of every month if it's a Monday)
#OnCalendar=*:0/15 (run script every 15 minutes)
OnUnitActiveSec=10s (run script every 10 seconds)
unit=script2.service

Here's the error I see when I look at the status of the service

script2.service - Script2 Logged-In Users
   Loaded: loaded (/etc/systemd/system/script2.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

Aug 08 15:17:38 localhost.localdomain script2[7918]: /root/Documents/Scripts/script2: line 3: Documents/UserFiles/useractivity.txt: No such file or directory
Aug 08 15:17:38 localhost.localdomain script2[7918]: /root/Documents/Scripts/script2: line 4: Documents/UserFiles/useractivity.txt: No such file or directory
Aug 08 15:17:38 localhost.localdomain systemd[1]: script2.service: main process exited, code=exited, status=1/FAILURE
Aug 08 15:17:38 localhost.localdomain systemd[1]: Unit script2.service entered failed state.
Aug 08 15:17:38 localhost.localdomain systemd[1]: script2.service failed.
Aug 08 15:24:44 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
Aug 08 15:25:44 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
Aug 08 15:28:19 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
Aug 08 15:29:34 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
Aug 08 15:45:58 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.

Here's what I get when I list the timers

NEXT                         LEFT     LAST                         PASSED       
Tue 2022-08-09 00:00:00 EDT  8h left  Mon 2022-08-08 11:17:23 EDT  4h 40min ago 
Tue 2022-08-09 12:16:53 EDT  20h left Mon 2022-08-08 12:16:53 EDT  3h 40min ago 
n/a                          n/a      n/a                          n/a          

Note: The first two are from a different process.

I'm not sure why the timer isn't working.

1 Answer 1

1

When you use OnUnitActiveSecs, that means:

Defines a timer relative to when the unit the timer unit is activating was last activated

Because the timer is relative to when the unit...was last activated, if you haven't started the unit since creating the timer, the timer will never trigger.

We can this with a simple example; if I create exampleservice.service with this content:

[Service]
Type = simple
ExecStart = /bin/sh -c 'date >> /tmp/datelog.txt'

And exampleservice.timer with this content:

[Timer]
OnUnitActiveSec=10s

And start the timer:

systemctl start exampleservice.timer

I can see that the timer has neither a "next" nor "last" execution time:

$ systemctl list-timers | grep example
n/a                         n/a           n/a                         n/a          exampleservice.timer                exampleservice.service

But if I start the service once:

systemctl start exampleservice

I see that the timer immediately has a "next" execution time:

$ systemctl list-timers | grep example
Mon 2022-08-08 18:17:15 EDT 9s left       n/a                         n/a         exampleservice.timer                exampleservice.service

And if I wait 10 seconds, I can see that it's executing periodically:

$ systemctl list-timers | grep example
Mon 2022-08-08 18:17:43 EDT 682ms left    Mon 2022-08-08 18:17:33 EDT 9s ago       exampleservice.timer                exampleservice.service

If you want periodic execution without needing to start the service first, take a look at the systemd.timer documentation:

Multiple directives may be combined of the same and of different types, in which case the timer unit will trigger whenever any of the specified timer expressions elapse. For example, by combining OnBootSec= and OnUnitActiveSec=, it is possible to define a timer that elapses in regular intervals and activates a specific service each time.

That's why you'll usually see OnBootSec and OnUnitActiveSec used in combination: that means "start N seconds after the system boots, and then execute every M seconds thereafter".

Alternately, you can use an OnCalendar entry to achieve the same thing:

[Timer]
OnCalendar = *-*-* *:*:00/10

This will run every 10 seconds.

3
  • This didn't work for me. I uncommented the OnCalendar line in the timer file and edited it to look like the one you showed, and started the service, but I get the same output (n/a n/a n/a systemd-readahead-done.timer) from systemctl --all timers
    – frank din
    Commented Aug 9, 2022 at 14:43
  • Did you start the timer? systemctl start <something>.timer If you were modifying an existing timer unit, did you systemctl daemon-reload?
    – larsks
    Commented Aug 9, 2022 at 14:45
  • No. I just did, and it worked. Thanks.
    – frank din
    Commented Aug 9, 2022 at 14:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .