Exécuter tout en étant vrai dans le script systemd

8

J'ai obtenu un script bash exécutant essentiellement ceci:

#!/bin/bash

[...]

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

Maintenant, je veux l'exécuter en tant que service systemd, mon script de service ressemble à ceci:

[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

Malheureusement, lorsque j'exécute ce service via, service somescript startcela fonctionne, mais à cause de la boucle while true, mon terminal est bloqué lors du démarrage du 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

Comment puis-je exécuter ce script en tant que service sans être bloqué dans la "boucle de démarrage" / while true?

Flatron
la source

Réponses:

8

Vous devez laisser systemd fonctionner pour vous. Laissez-le gérer la fourche au début et la mise à mort du processus. Par exemple, remplacez votre pièce de rechange par

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

alors vous pouvez utiliser systemctl start, statuset stop. Vous devez vous rappeler que les lignes de systemd ne sont PAS interprétées par le shell, donc par exemple votre &;est simplement passé comme un autre paramètre de 2 caractères à votre script.

meuh
la source
D'accord merci, j'ai fait les changements. Malheureusement, le script se bloque toujours lorsque vous essayez de le démarrer comme avant.
Flatron
1
Avez-vous pensé à faire sudo systemctl daemon-reload?
meuh
Vous savez ces moments où vous pensez que vous avez déjà fait quelque chose alors que vous ne l'avez pas fait? Merci ça marche! :)
Flatron
1

Selon vos besoins, vous pourriez envisager de remplacer votre boucle par une configuration de minuterie systemd. Il ne démarrera pas le service deux fois même si server_send_message prend plus de temps que "OnUnitActiveSec":

somescript.timer

[Unit]
Description=Announce every minute

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

[Install]
WantedBy=default.target

somescript.service Pièce de service:

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