it-swarm.com.de

Der "richtige" Weg, um zu testen, ob ein Dienst in einem Skript ausgeführt wird

Mein Problem:

Ich schreibe ein Bash-Skript und möchte darin überprüfen, ob ein bestimmter Dienst ausgeführt wird.

Ich weiß, wie man das manuell macht, mit $ service [service_name] status.

Aber (besonders seit der Umstellung auf systemd), das eine ganze Reihe von Texten druckt, deren Analyse etwas chaotisch ist. Ich nahm an, dass es einen Befehl für Skripte mit einfacher Ausgabe oder einen Rückgabewert gibt, den ich überprüfen kann.

Aber das Googeln ergibt nur eine Tonne "Oh, nur ps aux | grep -v grep | grep [service_name] "Ergebnisse. Das kann nicht die beste Vorgehensweise sein, oder? Was ist, wenn eine andere Instanz dieses Befehls ausgeführt wird, aber keine, die vom SysV-Init-Skript gestartet wurde?

Oder sollte ich einfach die Klappe halten und mir mit einem kleinen Pgrep die Hände schmutzig machen?

126
Nick S

systemctl hat ein is-active Unterbefehl dafür:

systemctl is-active --quiet service

wird mit dem Status Null beendet, wenn service aktiv ist, andernfalls ungleich Null, was es ideal für Skripte macht:

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

Wenn Sie --quiet Es wird auch der aktuelle Status an seine Standardausgabe ausgegeben.

Wie von don_crissti hervorgehoben, können einige Einheiten aktiv sein, obwohl nichts ausgeführt wird, um den Dienst bereitzustellen: Einheiten, die als „RemainAfterExit“ gekennzeichnet sind, gelten als aktiv, wenn sie erfolgreich beendet werden. Die Idee ist, dass sie einen Dienst bereitstellen die keinen Daemon benötigt ( zB sie konfigurieren einen Aspekt des Systems). Einheiten mit Dämonen sind jedoch nur aktiv, wenn der Dämon noch ausgeführt wird.

180
Stephen Kitt

systemctl verfügt über einen für die Skripterstellung geeigneten Modus. Verwenden Sie show anstelle von status und fügen Sie das -p/--properties und --value Optionen, um nur die gewünschte Ausgabe zu erhalten.

Hier ist ein Beispiel (von einem Ubuntu 17.04-System):

$ systemctl show -p SubState --value NetworkManager
running

Laufen (oder anders) ist ein SubState. Wenn Sie wissen möchten, ob ein Dienst aktiv ist, verwenden Sie die Eigenschaft ActiveState

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

Notizen aus dem 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 "=".
40
Zanna

Als Ergänzung zu Zannas Antwort wird das --value Option für systemctl show wurde mit Version 230 von systemd eingeführt. Daher ist es möglicherweise in bestimmten Distributionen wie Debian Jessie nicht verfügbar.

In diesem Fall kann man die Option mit sed emulieren:

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


Ich bin zu spät für die Party, aber die Verwendung von systemctl ist zusammen mit && Und || Aktiv. Dies im Skript wird nicht immer der Fall sein. Das Folgende ist eines, das ich für Tomcat verwendet habe, kann es jedoch in Methoden verwenden, die Argumente verwenden und den Dienstnamen als Argumente übergeben, wenn Sie mehrere Dienste überprüfen müssen, dies jedoch außerhalb des Gültigkeitsbereichs liegt.

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

So habe ich es genutzt ... Ich habe nur meine geteilt.

und für die Einfachheit und die einfachen Dinge folgen Sie anderen, die hier erklärt werden:

systemctl -q is-active Tomcat.service  && \
echo "Tomcat Runnung" || \
echo "Service is not running at all "
5
SAGAR Nair

ich finde dies nützlich für die Befehlszeilenausführung oder wenn Sie Skripte erstellen.

Von @StephenKitt kopiert

Dadurch wird überprüft, ob der Dienst nicht verfügbar ist, und ein Neustart des Dienstes durchgeführt

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

das || prüft dort, ob der Rückgabewert von systemctl ungleich Null ist, was bedeutet, wenn er nicht aktiv ist, wie vom Autor erläutert.

5
asterisk

Es gibt viele Antworten mit systemctl.

Sie haben auch andere Optionen (wobei $? ist praktisch):

  • Verwenden des Befehls pidof: Angenommen, ich versuche herauszufinden, ob der Redis-Server ausgeführt wird. Erste Ausgabe pidof redis-server und überprüfen Sie dann den Wert von $? Sie finden 0, wenn es ausgeführt wurde; sonst ungleich Null.
  • Dienstspezifische Lösung: Wenn der Dienst eine Möglichkeit bietet, zu überprüfen, ob der Dienst ausgeführt wird, können Sie diese verwenden. Für die redis-service Beispiel: Wenn der Dienst ausgeführt wird, erhalten wir eine PONG-Antwort für redis-cli ping Befehl. Nach der Ausgabe von redis-cli ping, Ich würde überprüfen $? und wenn es 0 ist, wird der Dienst ausgeführt.
2
Tuhin Paul

Anstatt den Befehl sed wie in der Antwort von Oxmel zu verwenden, reicht es aus, cut -d'=' -f 2 für alle Arten von abgefragten Eigenschaften:

zum Beispiel:

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

Funktioniert auch für ein Betriebssystem ohne System.

Wie wäre es mit ps -C service-name? prüfen $? zur Antwort. Wenn 0 es läuft, wenn 1, es läuft nicht.

Beispiel:

ps -C privoxy && echo running

Die leise Version:

ps -C privoxy 1>/dev/null && echo running

Vorsichtsmaßnahme :

Mir ist aufgefallen, dass Dienstnamen, die länger als 14 Zeichen sind, ein falsches Positiv ergeben können.

Siehe auch Kommentar von Nick S.

Beispiel:

Zeigt korrekt das Laufen an:

$ ps -C notification-daemon
  PID TTY          TIME CMD
 7418 ?        00:00:04 notification-da

Zeigt falsch läuft:

$ ps -C notification-daemon-fake
  PID TTY          TIME CMD
 7418 ?        00:00:04 notification-da

Zeigt korrekt an, dass nicht ausgeführt wird, da weniger als 14 Zeichen vorhanden sind:

$ ps -C notification
  PID TTY          TIME CMD

Ich habe diese Antwort von hier erhalten.

0
ajnabi