Il modo "corretto" per verificare se un servizio è in esecuzione in uno script


98

Il mio problema:

Sto scrivendo uno script bash e in esso mi piacerebbe verificare se un determinato servizio è in esecuzione.

So come farlo manualmente, con $ service [service_name] status.

Ma (specialmente dal passaggio a systemd) che stampa un sacco di testo che è un po 'disordinato da analizzare. Supponevo che ci fosse un comando per gli script con output semplice o un valore di ritorno che posso controllare.

Ma cercare su Google produce solo una tonnellata di risultati "Oh, just ps aux | grep -v grep | grep [service_name]". Non può essere la migliore pratica, vero? Cosa succede se è in esecuzione un'altra istanza di quel comando, ma non una avviata dallo script SysV init?

O dovrei solo stare zitto e sporcarmi le mani con un po 'di pgrep?

Risposte:


141

systemctlha un is-activesottocomando per questo:

systemctl is-active --quiet service

uscirà con lo stato zero se serviceè attivo, diverso da zero altrimenti, rendendolo ideale per gli script:

systemctl is-active --quiet service && echo Service is running

Se lo si omette --quiet, verrà inoltre visualizzato lo stato corrente sull'output standard.

Come sottolineato da don_crissti , alcune unità possono essere attive anche se non è in esecuzione nulla per fornire il servizio: le unità contrassegnate come "RemainAfterExit" sono considerate attive se escono correttamente, con l'idea che forniscono un servizio che non ha bisogno di un demone ( ad es. configurano alcuni aspetti del sistema). Le unità che coinvolgono demoni saranno comunque attive solo se il demone è ancora in esecuzione.


Attento ai servizi oneshot. Sono solo inactiveo activatingentrambi systemctl statused systemctl is-activeescono con 3. (come da systemd-241 ) Soluzione alternativa:systemctl show service | grep -qx ActiveStatus=activating
Alois Mahdal

@Alois Mi chiedo che tipo di scenari hai incontrato in cui vorresti considerare attivo un servizio oneshot; Hai un esempio?
Stephen Kitt,

Certo, @StephenKitt. Strumento foofa qualcosa al sistema che coinvolge il riavvio e utilizza un servizio one-shot, ad esempio, foo_cleanupal prossimo avvio per ripulire le cose. Sto testando questo (la mia sceneggiatura è anche programmata come servizio) e voglio raccogliere errori in seguito, ma quando è successiva (vsauce music)? Bene, uno dei criteri è che foo_cleanupè terminato ("ha smesso di essere attivo").
Alois Mahdal

Potrebbe valere la pena sottolineare che l'opzione "fallito" è anche un'opzione ed è utile se è necessario eseguire un'azione basata su un servizio non avviato.
Phill Healey,

33

systemctlha una modalità adatta per lo scripting; usa showinvece di status, e aggiungi le opzioni -p/ --propertiese --valueper ottenere solo l'output che desideri.

Ecco un esempio (da un sistema Ubuntu 17.04):

$ systemctl show -p SubState --value NetworkManager
running

Correre (o altrimenti) è a SubState. Se vuoi sapere se un servizio è attivo, usa la proprietàActiveState

$ systemctl show -p ActiveState --value x11-common
inactive
$ systemctl show -p SubState --value x11-common
dead

Note dal man:

show [PATTERN...|JOB...]
           Show properties of one or more units, jobs, or the manager
           itself. If no argument is specified, properties of the
           manager will be shown. If a unit name is specified, properties
           of the unit are shown, and if a job ID is specified,
           properties of the job are shown. By default, empty properties
           are suppressed. Use --all to show those too. To select specific
           properties to show, use --property=. This command is intended
           to be used whenever computer-parsable output is required. Use
           status if you are looking for formatted human-readable output.

-p, --property=
           When showing unit/job/manager properties with the show command,
           limit display to properties specified in the argument. The
           argument should be a comma-separated list of property names,
           such as "MainPID". Unless specified, all known properties are
           shown. If specified more than once, all properties with the
           specified names are shown. Shell completion is implemented for
           property names.

--value
           When printing properties with show, only print the value, and
           skip the property name and "=".

2
+1 per una risposta sofisticata. specificare gentilmente le distro che accetteranno l' --versionopzione con systemctl.
SK Venkat,

11

A complemento della risposta di Zanna, l' --valueopzione per systemctl showè stata introdotta con la versione 230 di systemd . Quindi potrebbe non essere disponibile su alcune distro come debian jessie.

In questo caso, si può emulare l'opzione usando sed:

$ systemctl show -p ActiveState sshd | sed 's/ActiveState=//g'
active
$ systemctl show -p SubState sshd | sed 's/SubState=//g'  
running

1
+1 per sottolineato la versione introduttiva --value e la distro che non funzioneranno.
SK Venkat,

3

lo trovo utile per l'esecuzione da riga di comando o se stai scrivendo degli script.

Copiato da @StephenKitt

Questo verificherà se il servizio non è attivo ed eseguirà il riavvio del servizio

systemctl is-active --quiet <service name> || <service name> restart

la ||si controlla se il valore restituito da systemctl è non-zero significato se non è attiva come spiegato dall'autore.


Puoi anche usare `is-failed´ per verificare se è necessario un riavvio. Sembra un po 'più intuitivo per riavviare un servizio fallito.
Phill Healey,

si, ma per me .. volevo esercitarmi e supporre che tutto funzioni quando non lo è. così posso andare cose verificare altre cose con esso. semplicemente se vuoi solo controllare se non è in esecuzione, allora 'è fallito' è una scelta giusta. :)
asterisco

3


Sono troppo tardi per la festa, tuttavia l'uso di systemctl è attivo insieme &&e ||per questo nella sceneggiatura non sarà sempre così. Quello che segue è uno che ho usato per Tomcat ma posso usarlo nel metodo prendendo argomenti e passare il nome del servizio come argomenti se devi controllare più servizi ma è fuori portata qui.

STATUS=`systemctl is-active tomcat.service`
  if [[ ${STATUS} == 'active' ]]; then
    echo "Execute your tasks ....."
  else 
    echo " Service not running.... so exiting "  
    exit 1  
  fi

Questo è il modo in cui ho fatto uso ... Condivido solo il mio.

e per la semplicità e le cose facili, segui gli altri spiegati qui:

systemctl -q is-active tomcat.service  && echo "Tomcat Runnung" || echo "Service is not running at all "

Come è meglio che semplicemente if systemctl is-active --quiet tomcat.service? Inoltre, [[non è shell standard.
Toby Speight,

@TobySpeight Devi leggere un po 'di più il mio post, come ho già detto nel mio post "Questo è il modo in cui ho fatto uso di ... Solo condividendo il mio." Non ho mai detto, è un uso di shell standard, se lo fai tra parentesi singole, diventerà allora, ma questo è fuori portata qui. Inoltre, di seguito menziono un facile utilizzo a linea singola per farlo usando &&e ||.
SAGAR Nair,

2

Invece di usare il comando sed come nella risposta di Oxmel, è sufficiente usare cut -d'=' -f 2per tutti i tipi di proprietà interrogate:

per esempio:

$ systemctl show -p ActiveState sshd | cut -d'=' -f2
active
$ systemctl show -p SubState sshd | cut -d'=' -f2
running

È fantastico, ma devi davvero dare una spiegazione su cosa fanno quei comandi.
Phill Healey,

-1

Ho appena trovato questo fantastico piccolo copione:

#!/bin/bash
service=replace_me_with_a_valid_service

if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
then
  echo "$service is running!!!"
else
  /etc/init.d/$service start
fi

fonte


Non tutti i servizi hanno un eseguibile con lo stesso nome e qualsiasi utente potrebbe eseguire un comando che corrisponde per errore: questa è una ricetta per il disastro.
Toby Speight,
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.