0

at the system start, using a systemd service, I want to lauch a bash to run forever, executing an action every 5 seconds.

Its code is simple (do_every_5_segons.sh)

    while true
    do
        {read some JSON from internet} >> $myLogFile  2>&1
        sleep 5
    done

So, in my service definition I write (~/.config/systemd/user/r4_start.service )

    pi@R4:
    [Unit]
    Description=R4 start 
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    Restart=no
    WorkingDirectory=/home/pi/tools
    ExecStart=/home/pi/tools/r4_start.sh

And in the "r4_start.sh", I do some trace and then launch my bash :

    nohup /home/pi/python/do_every_5_segons.sh &

The "&" is required so more init can be done after this line.

The "nohup" is required so the shell survives parent end.

My question is :

  • what is the correct service "Type" for this situation ?
Mikel Vergy
  • 121
  • 5
  • oneshot is exactly the wrong thing for anything you want to run forever. Just taking it out and using the default service type would be better. – Charles Duffy May 23 '22 at 23:05
  • And you should _never_ use nohup in a service. If you think you need it for any reason, you are wrong. The parent is PID 1; it survives as long as the system is booted; there _is_ no end that needs to be survived. Similarly, you should stay in the foreground; do not try to daemonize. – Charles Duffy May 23 '22 at 23:06
  • BTW, in English it's "seconds", not "segons". – Charles Duffy May 23 '22 at 23:10
  • Thanks, Charles - never shall use NOHUP in a service - you are 100 % right – Mikel Vergy May 23 '22 at 23:12
  • my filename mixes english and catalan (do_every_5_segons.sh) – Mikel Vergy May 23 '22 at 23:12
  • "using the default service type" .. what type is this ? I prefer to specify one, so I can read the manuals. – Mikel Vergy May 23 '22 at 23:16
  • The default is `simple`. – Charles Duffy May 23 '22 at 23:21
  • From the tag: systemd questions should be for *programming questions* using systemd or its libraries. Questions about *configuring the daemon* (including writing unit files) are better directed to Unix & Linux: https://unix.stackexchange.com. – Rob May 24 '22 at 09:54

1 Answers1

1

Do not use nohup. Do not use &. Do not wrap your script in another script. Doing either of these first two things stops systemd from detecting when your program crashed and restarting it, and the third complicates signal handling.

Do use Restart=always. Do create an Install section, and configure your service to be a dependency of a target that is started on boot.

[Unit]
Description=R4 start 

[Service]
WorkingDirectory=/home/pi/tools
ExecStart=/home/pi/tools/run-poll-loop
Restart=always

[Install]
WantedBy=multi-user.target

...where run-poll-loop is executable (chmod +x) and contains your logic (note, command names should not have extensions; .sh is bad practice):

#!/usr/bin/env bash
while :; do
  # ...do whatever you need here...
  sleep 5
done

Note that for a slower delay than every-5-seconds, I would suggest a systemd timer running a oneshot service that only does a single iteration of the loop each time; but for this short a timer, that would add up to quite a bit of process-startup overhead.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • well, what you are saying here is "do not have one BIG init" service, but lots of small. Am I right ? – Mikel Vergy May 23 '22 at 23:14
  • @MikelVergy, what do you mean? systemd is an init system itself. There's no need to create more init systems under it; if one is going to use systemd (or another process supervisor -- personally, I'm very fond of [`runit`](http://smarden.org/runit/) or [`s6`](https://skarnet.org/software/s6/)), one should actually take advantage of what it offers. – Charles Duffy May 23 '22 at 23:15
  • again you are right. Tonite I am learning big, thanks, Charles. – Mikel Vergy May 23 '22 at 23:17
  • BTW, the list of run scripts for runit at http://smarden.org/runit/runscripts.html might be interesting for you to read -- as you'll see, much of what it contains is information about how to _turn off_ different services' self-daemonization to allow those programs to be properly monitored and controlled by the supervisor running them. That's pretty much the same as the steps needed to make a service safe to use by systemd with the default `Type=simple`. – Charles Duffy May 23 '22 at 23:18
  • I shalll have a read in 5 minutes, but, to end my question .. what (explicit) service "Type" shall I use ? one-shot is the wrong one ... – Mikel Vergy May 23 '22 at 23:21
  • ok - Type=simple – Mikel Vergy May 23 '22 at 23:22
  • :-)) very intersting "Command names should never have filename extensions" – Mikel Vergy May 23 '22 at 23:26
  • The author is an old friend of mine, but that I'm not just linking the essay out of favoratism -- it's long been part of the bash IRC channel's factoid database; see https://wooledge.org/~greybot/meta/.sh with the history of the relevant entry (the second column is a timestamp in seconds-since-epoch for each change; newest version at the end). – Charles Duffy May 23 '22 at 23:29