Esegui mentre è vero nello script di systemd


8

Ho ottenuto uno script bash essenzialmente su questo:

#!/bin/bash

[...]

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

Ora voglio eseguire questo come un servizio systemd, il mio script di servizio è simile al seguente:

[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

Sfortunatamente quando eseguo questo servizio tramite service somescript startesso funziona, ma a causa del ciclo while true il mio terminale è bloccato all'avvio dello 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

Come posso eseguire questo script come un servizio senza rimanere bloccato nel ciclo "startup" / while true?

Risposte:


8

Devi lasciare che systemd lavori per te. Lascia che gestisca il fork all'inizio e l'uccisione del processo. Ad esempio, sostituire la parte di servizio con

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

allora puoi usare systemctl start, statuse stop. Devi ricordare che le righe in systemd NON sono interpretate dalla shell, quindi ad esempio il tuo &;è semplicemente passato come un altro parametro di 2 caratteri al tuo script.


Ok grazie, ho fatto i cambiamenti. Purtroppo lo script si blocca ancora quando si tenta di avviarlo come prima.
Flatron,

1
Ti sei ricordato di fare sudo systemctl daemon-reload?
Meuh

Conosci questi momenti che pensi di aver già fatto qualcosa, ma non l'hai fatto? Grazie funziona! :)
Flatron,

1

A seconda delle esigenze, potresti considerare di sostituire il tuo loop con una configurazione del timer di sistema. Il servizio non verrà avviato due volte anche se server_send_message impiega più tempo di "OnUnitActiveSec":

somescript.timer

[Unit]
Description=Announce every minute

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

[Install]
WantedBy=default.target

somescript.service Parte del servizio:

[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c 'str="broadcast "`randArrayElement "messages[@]"`; server_send_message $str'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.