Wie teste ich (in einer Zeile), ob die Befehlsausgabe eine bestimmte Zeichenfolge enthält?

75

Wie kann ich in einer Bash-Zeile einen Exit-Status von 0 zurückgeben, wenn die Ausgabe von /usr/local/bin/monit --versionnicht genau enthält, 5.5und einen Exit-Status von 1, wenn dies der Fall ist?

Däne O'Connor
quelle

Antworten:

103
! /usr/local/bin/monit --version | grep -q 5.5

( grepGibt den Exit-Status 0 zurück, wenn eine Übereinstimmung gefunden wird, und andernfalls 1. Die -qOption "leise" weist an, keine gefundene Übereinstimmung zu drucken. Mit anderen Worten, grepdas einzige, was Sie möchten, ist die Rückgabe -Wert. Der !am Anfang kehrt den Exit-Status der gesamten Pipeline um.)

Bearbeitet, um hinzuzufügen: Alternativ grepkönnen Sie schreiben , wenn Sie dies in "pure Bash" tun möchten (anstatt anzurufen ):

[[ $(/usr/local/bin/monit --version) != *5.5* ]]

( [[...]]wird in §3.2.4.2 "Bedingte Konstrukte" des Bash-Referenzhandbuchs erläutert . *5.5*ist genau wie in Fileglobs: null oder mehr Zeichen plus 5.5plus plus null oder mehr Zeichen.)

Ruakh
quelle
Effing Genie! Die Kraft der Pfeife ist immer wieder beeindruckend.
Joshua Pinter
Gibt es eine Möglichkeit, den Wert eines /usr/local/bin/monit --versionFehlschlags wiederzugeben?
Joshua Pinter
@JoshuaPinter: Bitte klären Sie - was meinen Sie mit "wenn es fehlschlägt"? (Welche Richtung ist "Misserfolg"?)
Ruakh
@ruakh Wenn der Exit-Code 1 ist, kann er den monit --versionWert anzeigen , während er noch mit dem Status 1 beendet wird?
Joshua Pinter
1
@ JoshuaPinter: Das scheint gleichbedeutend mit monit --version; monit --version | grep -q 5.5; aber ich vermute, du wolltest verwenden grep -qanstatt nackt grep? In diesem Fall könnten Sie etwas vereinfachen monit --version | grep -q 5.5 || (monit --version; false). Und - monit --versiondruckt jemals mehrere Zeilen? Wenn nicht, können Sie auf einfach vereinfachen ! monit --version | grep -v 5.5.
Ruakh
27
[ $(/usr/local/bin/monit --version) == "5.5" ] 

zB-1: auf Erfolg prüfen

[ $(/usr/local/bin/monit --version) == "5.5" ] && echo "OK"

zB-2: auf Fehler prüfen

    [ $(/usr/local/bin/monit --version) == "5.5" ] || echo "NOT OK"

oder, um nur zu überprüfen, ob die Ausgabe Folgendes enthält 5.5:

[[ $(/usr/local/bin/monit --version) =~ "5.5" ]] || echo "NOT OK"
perreal
quelle
"5.5" ist Teil einer größeren Ausgabe.
Dane O'Connor
@perreal - Sie können Regex nicht in Bash zitieren, es macht es eher zu einer wörtlichen Zeichenfolge als zu einem Regex. (Zitieren funktioniert in einigen älteren Versionen von Bash, wurde aber als Fehler behoben).
Jordanm
@ Jordanm, das ist nicht richtig. Wenn Sie 5.5 nicht zitieren, entspricht es auch 5a5. Die Anführungszeichen machen den Punkt zu einer Zeichenfolge.
Perreal
1
@perreal Ich habe es gerade getestet. [[ "5a5" =~ "5.5" ]] && echo yesdruckt nichts als [[ "5a5" =~ 5.5 ]] && echo yesja drucken. Die zitierte Version funktioniert in zsh, aber nicht in bash.
Jordanm
2

Testen Sie den Rückgabewert von grep:

sudo service xyz status | grep 'not' &> /dev/null
if [ $? == 0 ]; then
   echo "whateveryouwant"
fi

Ich würde cron empfehlen, es funktioniert gut mit SALT Stack

Matzy
quelle