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
      CommentedAug 17, 2016 at 11:43
    • 1
      Did you remember to do sudo systemctl daemon-reload?
      – meuh
      CommentedAug 17, 2016 at 11:52
    • You know these moments you think you already did something though you did not? Thanks it works! :)
      – Bent
      CommentedAug 17, 2016 at 11:55
    • in my case i have to add /bin/bash tooCommentedSep 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
      CommentedSep 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.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.