8

I got a bash script essentially runnning this:

#!/bin/bash

[...]

 while true; do
         str="broadcast "`randArrayElement "messages[@]"`
         server_send_message $str
         sleep $interval
 done

Now I want to run this as a systemd service, my service script looks like this:

[Unit]
Description=Announcer
After=network.target

[Service]
ExecStart=/usr/local/bin/somescript &; disown
ExecStop=/usr/bin/kill -9 `cat /tmp/somescript.pid`
Type=forking
PIDFile=/tmp/somescript.pid

[Install]
WantedBy=default.target

Unfortunately when I run this service via service somescript start it is working but because of the while true loop my terminal is stuck in starting the script:

● somescript.service - somescript service
   Loaded: loaded (/etc/systemd/system/somescript.service; disabled; vendor preset: enabled)
   Active: activating (start) since Wed 2016-08-17 12:22:34 CEST; 43s ago
  Control: 17395 (somescript)
   CGroup: /system.slice/somescript.service
           ├─17395 /bin/bash /usr/local/bin/somescript &; disown
           └─17409 sleep 600

How can I run this script as a service without being stuck in "starting" / the while true loop?

2 Answers 2

11

You need to let systemd work for you. Let it handle the forking at the start and the killing of the process. Eg replace your service part by

[Service]
Type=simple
ExecStart=/usr/local/bin/somescript
PIDFile=/tmp/somescript.pid

then you can use systemctl start, status and stop. You must remember that the lines in systemd are NOT interpreted by the shell, so for example your &; is merely passed as another parameter of 2 characters to your script.

5
  • Okay thanks, I did the changes. Unfortunately the script still hangs when trying to start it as before.
    – Bent
    Aug 17, 2016 at 11:43
  • 1
    Did you remember to do sudo systemctl daemon-reload?
    – meuh
    Aug 17, 2016 at 11:52
  • You know these moments you think you already did something though you did not? Thanks it works! :)
    – Bent
    Aug 17, 2016 at 11:55
  • in my case i have to add /bin/bash too Sep 25, 2021 at 19:58
  • 1
    @ImranRazaKhan Make sure you have done chmod a+rx on your script file so that it is executable, and that the first line is #!/bin/bash if it is a bash script.
    – meuh
    Sep 26, 2021 at 14:40
1

Depending on your requirements you might consider to replace your loop by a systemd timer configuration. It will not start service twice even if server_send_message takes longer than "OnUnitActiveSec":

somescript.timer

[Unit]
Description=Announce every minute

[Timer]
OnUnitActiveSec=1m
AccuracySec=10s
Unit=somescript.service

[Install]
WantedBy=default.target

somescript.service Service part:

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c 'str="broadcast "`randArrayElement "messages[@]"`; server_send_message $str'

You must log in to answer this question.

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