Testen, ob ein Prozess über if und -z ausgeführt wird

2

Ich habe einen Prozess auf meinem System, der bekanntermaßen abstürzt und geschäftskritisch ist, mein Netzwerkmanager. In jedem Fall muss ich eine Schleife schreiben, die prüft, ob sie ausgeführt wird, und sie startet, wenn sie nicht ausgeführt wird. Folgendes habe ich mir bisher ausgedacht:

#!/bin/bash

while [ true ]; do 
    if [ -z $(ps aux | grep "[n]m-applet") ]; then
        echo "Bugger died, resurrecting..."
        nm-applet >/dev/null 2>/dev/null &
        disown $!
    fi

    sleep 3
done 

Leider ist dies nicht ganz der richtige Trick, da es den Prozess auch dann zu starten scheint, wenn er nicht erforderlich ist. Nach dem ersten Durchlauf erhalte ich die folgende Fehlermeldung:

line 4: [: too many arguments

Was mache ich hier falsch?

Naftuli Kay
quelle
while [ true ]; do ...wird interpretiert als while [ -n "true" ]; do ...; Das heißt, es wird geprüft, ob die Zeichenfolge "true" nicht leer ist. Dies ergibt dasselbe Ergebnis wie while true; do ...oder while :; do ...welches wahrscheinlich das ist, was Sie verwenden wollten. (Dies ist nicht dazu gedacht, Ihre Frage zu beantworten. Die folgenden Antworten machen das richtig. Es ist nur ein
Nebenkommentar

Antworten:

9

Versuchen Sie, das $(...)in doppelte Anführungszeichen zu setzen:

if [ -z "$(ps aux | grep '[n]m-applet')" ]; then

Vielleicht möchten Sie es aber mit pgrepoder versuchen ps axo cmd | grep '[n]m-applet'.

Arcege
quelle
Sieht aus wie es funktioniert!
Naftuli Kay
6

Dieser Fehler ergibt sich aus der Angabe mehrerer Argumente für -z. Es ist ein unärer Operator, und wenn der Operator $()zu etwas erweitert wird, in dem sich $ IFS befindet, werden mehrere Argumente angezeigt. Um dies zu beheben, können Sie Anführungszeichen um es wie so setzen: [ -z "$(ps...)" ].

In diesem Fall benötigen Sie den test ( []) nicht, da grep einen Wert ungleich Null zurückgibt, wenn nichts gefunden wird. Du kannst tun:

if ps aux | grep '[n]m-applet' > /dev/null; then

Und Sie möchten vielleicht sehen, ob die Systeme, die Sie bereitstellen möchten, über diese verfügen pgrep. Es ist dafür gemacht, nach Prozessen zu suchen, die einem Muster entsprechen.

Außerdem möchten Sie möglicherweise, dass das Skript das nm-Applet nicht im Hintergrund ausführt. Auf diese Weise wird das Skript blockiert, bis das nm-Applet stirbt.

Schließlich möchten Sie vielleicht Monit anschauen , das dafür gemacht ist, was Ihr Skript tut.

Shawn J. Goff
quelle
2
Möglicherweise möchten Sie entweder -szu grep hinzufügen oder stdout ( >&-) schließen, um zu verhindern, dass die Ausgabe an den Benutzer gelangt.
Arcege
Danke, @Arcege; Ich habe es mit `> / dev / null 'bearbeitet.
Shawn J. Goff
3

Ich bin mir nicht sicher, aus welchen Gründen Sie das gemacht haben, while [ true ]; dound bin dem Vorschlag von Arcege gefolgtpgrep .

#!/bin/bash
while true; do 
    if ! pgrep nmapplet &>/dev/null; then
       echo "Bugger died, resurrecting..."
       nm-applet &>/dev/null
       disown $!
    fi
    sleep 3
done
jasonwryan
quelle
Sie müssen das pgrepInnere der Endlosschleife setzen
Glenn Jackman
@glenn Stört es Sie zu erklären, warum? Die Variable ist nicht genug?
Jasonwryan
Sie legen die Variable fest, wenn Sie das Skript starten. Selbst wenn der Prozess abbricht, schlägt der "-z" -Test niemals fehl, da sich die Variable niemals ändert.
Glenn Jackman
Einfachere Verwendung des Exit-Status. Aktualisiert.
Mikel