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?

8

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.

  • Okay thanks, I did the changes. Unfortunately the script still hangs when trying to start it as before. – Flatron Aug 17 '16 at 11:43
  • 1
    Did you remember to do sudo systemctl daemon-reload? – meuh Aug 17 '16 at 11:52
  • You know these moments you think you already did something though you did not? Thanks it works! :) – Flatron Aug 17 '16 at 11:55
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'

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.