1

I wrote a very simple script (checkaudio.sh) that publishes a message from a file on a mqtt topic. I would like the script to run continuously (I would be happy even with every second). I first tried with cron, which is technically possible but "dirty" as a solution (multiple cron jobs with a 1 second delay each).

I have the tried with systemd and its timer function. I'm not very proficient with systemd, and this is what I came up with:

/etc/systemd/system/checkaudio@root.service contents:

[Unit]
Description=Announce every second

[Install]
WantedBy=default.target

[Service]
Type=oneshot
ExecStart=/root/checkaudio.sh

/etc/systemd/system/checkaudio@root.timer contents:

[Timer]
OnUnitActiveSec=1s
AccuracySec=1ms
Unit=checkaudio@root.service

I activated the two above through systemctl enable. Everything was running smoothly until I rebooted the system and I could not enable /etc/systemd/system/checkaudio@root.timer anymore. I am getting the following error:

The unit files have no installation config (WantedBy, RequiredBy, Also, Alias
settings in the [Install] section, and DefaultInstance for template units).
This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
   .wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
   a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
   D-Bus, udev, scripted systemctl call, ...).
4) In case of template units, the unit is meant to be enabled with some
   instance name specified.

What am I doing wrong? Is there a better way to achieve my initial objective of running the script continuously?

2

Your .timer unit (not the .service unit, which has one but probably shouldn't) is missing an [Install] section.

You probably want to add:

[Install]
WantedBy=timers.target

Your .service file is intended to be activated only by the timer, not directly during boot (etc.). So it shouldn't have an [Install] section (and shouldn't be systemctl enable'd).

2
  • Thank you very much for your answer. I actually do want my script to be started during boot, or the timer will take care of that? – giovi321 Dec 14 '19 at 7:55
  • @giovi321 add OnBootSec to your timer unit. That'll get the first run on boot. (As the systemd.timer manpage puts it, "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.") – derobert Dec 14 '19 at 8:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.