„Właściwy” sposób sprawdzenia, czy usługa działa w skrypcie


96

Mój problem:

Piszę skrypt bash, w którym chciałbym sprawdzić, czy dana usługa jest uruchomiona.

Wiem, jak to zrobić ręcznie, za pomocą $ service [service_name] status.

Ale (zwłaszcza od przejścia na systemd) drukuje całą wiązkę tekstu, który jest nieco niechlujny do przeanalizowania. Zakładałem, że istnieje polecenie dla skryptów z prostym wyjściem lub zwracana wartość, którą mogę sprawdzić.

Ale Googling przynosi tylko mnóstwo wyników „Och, tylko ps aux | grep -v grep | grep [service_name]”. To nie może być najlepsza praktyka, prawda? Co się stanie, jeśli uruchomiona zostanie inna instancja tej komendy, ale nie uruchomiona przez skrypt inicjujący SysV?

A może powinienem się zamknąć i zabrudzić ręce odrobiną pgrep?

Odpowiedzi:


139

systemctlma is-activedo tego komendę:

systemctl is-active --quiet service

wyjdzie ze stanu zero, jeśli servicejest aktywny, w przeciwnym razie niezerowy, co czyni go idealnym do skryptów:

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

Pominięcie --quietspowoduje wyświetlenie bieżącego stanu na standardowe wyjście.

Jak zauważył don_crissti , niektóre jednostki mogą być aktywne, nawet jeśli nic nie działa w celu świadczenia usługi: jednostki oznaczone jako „RemainAfterExit” są uważane za aktywne, jeśli zakończą się powodzeniem, przy założeniu, że zapewniają usługę, która nie potrzebuje demona ( np . konfigurują jakiś aspekt systemu). Jednostki obejmujące demony będą jednak aktywne tylko wtedy, gdy demon nadal działa.


Uważaj na usługi oneshot. Są tylko inactivelub activatingoba systemctl statusi systemctl is-activewychodzą z 3. (od systemd-241 ) Obejście:systemctl show service | grep -qx ActiveStatus=activating
Alois Mahdal

@ Allois Zastanawiam się, jakie napotkaliście scenariusze, w których chcieliby Państwo uznać usługę oneshot za aktywną; masz przykład?
Stephen Kitt

Jasne, @StephenKitt. Narzędzie foorobi coś w systemie obejmującym ponowne uruchomienie i używa jednorazowej usługi, powiedzmy, foo_cleanupprzy następnym uruchomieniu do czyszczenia. Jestem testowania to (mój skrypt jest również zaplanowane jako usługa) i chcesz odebrać błędy później, ale kiedy jest później (muzyka Vsauce)? Cóż, jednym z kryteriów jest to, że foo_cleanupsię skończyło („przestał być aktywny”).
Alois Mahdal

Warto zauważyć, że opcja „nie powiodła się” jest również opcją i jest przydatna, jeśli konieczne jest wykonanie akcji na podstawie usługi, która nie została uruchomiona.
Phill Healey

33

systemctlma tryb odpowiedni dla skryptów; użyj showzamiast status, i dodaj opcje -p/ --propertiesi, --valueaby uzyskać tylko pożądany wynik.

Oto przykład (z systemu Ubuntu 17.04):

$ systemctl show -p SubState --value NetworkManager
running

Uruchamianie (lub w inny sposób) to SubState. Jeśli chcesz wiedzieć, czy usługa jest aktywna, skorzystaj z właściwościActiveState

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

Uwagi z 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 za wyrafinowaną odpowiedź. uprzejmie określ dystrybucje, które zaakceptują --versionopcję z systemctl.
SK Venkat

11

Jako uzupełnienie odpowiedzi Zanny wprowadzono --valueopcję dla wersji 230 systemd . Więc może nie być dostępny w niektórych dystrybucjach, takich jak debian jessie.systemctl show

W takim przypadku można emulować opcję za pomocą sed:

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

1
+1 za wskazaną wersję i dystrybucję --value intro, która nie będzie działać.
SK Venkat

3

Uważam to za przydatne do wykonywania wiersza poleceń lub jeśli tworzysz skrypty.

Skopiowano z @StephenKitt

Spowoduje to sprawdzenie, czy usługa jest wyłączona i ponowne uruchomienie usługi

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

||nie sprawdza, czy wartość zwracana z systemctl jest niezerowe sens, jeśli nie jest aktywny, jak wyjaśniono przez autora.


Możesz także użyć „is-failed”, aby sprawdzić, czy konieczne jest ponowne uruchomienie. Ponowne uruchomienie uszkodzonej usługi wydaje się nieco bardziej intuicyjne.
Phill Healey

tak, ale dla mnie .. chciałem ćwiczyć i zakładać, że wszystko działa, a nie jest. abym mógł przejść do weryfikacji innych rzeczy. po prostu jeśli chcesz tylko sprawdzić, czy nie działa, to „nie powiodło się” jest właściwym wyborem. :)
gwiazdka

3


Jestem zbyt późno do partii, jednak stosując systemctl jest czynne wraz z &&i ||do tego w skrypcie przyzwyczajenie być tak cały czas. Poniżej jest jeden, którego użyłem dla tomcat, ale mogę go użyć w metodzie przyjmującej argumenty i przekazując nazwę usługi jako argumenty, jeśli musisz sprawdzić wiele usług, ale jest to poza zakresem tutaj.

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

W ten sposób wykorzystałem .... Po prostu udostępniając moje.

a dla uproszczenia i łatwych rzeczy postępuj zgodnie z innymi wyjaśnionymi tutaj:

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

Jak to jest lepsze niż po prostu if systemctl is-active --quiet tomcat.service? Ponadto [[nie jest standardową powłoką.
Toby Speight

@TobySpeight Musisz przeczytać trochę więcej mojego postu, jak wspomniałem w moim poście „W ten sposób wykorzystałem ... Po prostu udostępniam mój”. Nigdy nie mówiłem, że to standardowe użycie powłoki, jeśli uczynisz ją pojedynczym nawiasiem, stanie się wtedy, ale to nie wchodzi w zakres tutaj. Ponadto poniżej wspominam o łatwym użyciu pojedynczej linii, aby to zrobić za pomocą &&i ||.
SAGAR Nair

2

Zamiast używać polecenia sed, jak w odpowiedzi Oxmela, wystarczy użyć cut -d'=' -f 2dla wszystkich zapytanych właściwości:

na przykład:

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

To świetnie, ale naprawdę musisz wyjaśnić, co robią te polecenia.
Phill Healey

-1

Właśnie znalazłem ten świetny mały skrypt:

#!/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

Źródło


Nie wszystkie usługi mają plik wykonywalny o tej samej nazwie, a każdy użytkownik może uruchomić polecenie, które przypadkowo pasuje - jest to przepis na katastrofę.
Toby Speight
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.