Run while true no script systemd

8

Eu tenho um script bash essencialmente rodando isso:

#!/bin/bash

[...]

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

Agora, quero executar isso como um serviço systemd, meu script de serviço é assim:

[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

Infelizmente quando eu executo este serviço via service somescript start ele está funcionando, mas por causa do while true loop meu terminal está preso em iniciar o 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

Como posso executar este script como um serviço sem ficar preso em "iniciar" / while loop verdadeiro?

    
por Flatron 17.08.2016 / 12:32

2 respostas

8

Você precisa deixar o systemd trabalhar para você. Deixe-o lidar com a bifurcação no início e a morte do processo. Por exemplo, substitua sua peça de serviço por

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

você pode usar systemctl start , status e stop . Você deve lembrar que as linhas no systemd são NOT interpretadas pelo shell, portanto, por exemplo, seu &; é simplesmente passado como outro parâmetro de 2 caracteres para o seu script.

    
por 17.08.2016 / 13:34
0

Dependendo de seus requisitos, você pode considerar substituir seu loop por uma configuração de timer do systemd. Ele não iniciará o serviço duas vezes, mesmo se server_send_message demorar mais do que "OnUnitActiveSec":

somescript.timer

[Unit]
Description=Announce every minute

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

[Install]
WantedBy=default.target

peça de serviço somescript.service:

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c 'str="broadcast "'randArrayElement "messages[@]"'; server_send_message $str'
    
por 11.02.2018 / 17:06