Wie verwende ich einen Datei-Grep-Vergleich in einer Bash-if / else-Anweisung?

138

Wenn unser Server hochfährt, müssen wir eine Datei überprüfen, um festzustellen, wie der Server konfiguriert ist.

Wir möchten in unserer Datei /etc/aws/hosts.conf nach der folgenden Zeichenfolge suchen:

MYSQL_ROLE=master

Anschließend möchten wir testen, ob diese Zeichenfolge vorhanden ist, und mithilfe einer if / else-Anweisung eine von zwei Optionen ausführen, je nachdem, ob die Zeichenfolge vorhanden ist oder nicht.

Wie lautet die BASH-Syntax für die if-Anweisung?

if [ ????? ]; then
  #do one thing
else
  #do another thing
fi
user77413
quelle

Antworten:

205

Von grep --help, aber auch Mann grep sehen :

Der Beendigungsstatus ist 0, wenn eine Zeile ausgewählt wurde, andernfalls 1; Wenn ein Fehler auftritt und -q nicht angegeben wurde, lautet der Exit-Status 2.

if grep --quiet MYSQL_ROLE=master /etc/aws/hosts.conf; then
  echo exists
else
  echo not found
fi

Möglicherweise möchten Sie einen spezifischeren regulären Ausdruck verwenden, z. B. ^MYSQL_ROLE=master$um diese Zeichenfolge in Kommentaren, Namen, die lediglich mit "master" beginnen, usw. zu vermeiden.

Dies funktioniert, weil das if einen Befehl nimmt und ausführt und anhand des Rückgabewerts dieses Befehls entscheidet, wie vorgegangen werden soll. Null bedeutet wahr und ungleich Null bedeutet falsch - genau wie andere Rückkehrcodes von der Shell interpretiert werden. und das Gegenteil einer Sprache wie C.


quelle
> mit null für wahr und ungleich null für falsch - genauso wie andere Rückkehrcodes von der Shell interpretiert werden und das Gegenteil einer Sprache wie C., aber warum das Gegenteil ...?
Kchoi
Weil eine Null normalerweise als "kein Fehler" interpretiert wird, während alles andere "ein Fehler" bedeutet. Wenn davon ausgegangen wird, möchten wir wissen, ob der Befehl erfolgreich ausgeführt wurde.
Timelmer
33

ifNimmt einen Befehl und überprüft seinen Rückgabewert. [ist nur ein Befehl.

if grep -q ...
then
  ....
else
  ....
fi
Ignacio Vazquez-Abrams
quelle
23

Beachten Sie, dass für PIPEjeden Befehl oder jede Befehlsfolge Folgendes gilt:

if PIPE ; then
  # do one thing if PIPE returned with zero status ($?=0)
else 
  # do another thing if PIPE returned with non-zero status ($?!=0), e.g. error
fi 

Für die Aufzeichnung [ expr ]ist eine Shell in Kurzform für gebaut test expr.

Da grepbei einer Übereinstimmung der Status 0 und bei Nichtübereinstimmung der Status ungleich Null zurückgegeben wird, können Sie Folgendes verwenden:

if grep -lq '^MYSQL_ROLE=master' ; then 
  # do one thing 
else 
  # do another thing
fi 

Beachten Sie, dass bei der Verwendung -lnur darauf geachtet wird, dass die Datei mindestens eine Übereinstimmung aufweist (sodass diese grepzurückgegeben wird, sobald eine Übereinstimmung gefunden wird, ohne dass die Eingabedatei unnötig weiter analysiert werden muss).

auf einigen Plattformen [ expr ]ist kein builtin, sondern eine tatsächliche ausführbare /bin/[(dessen letzte Argument sein wird ]), weshalb [ expr ]Zuschnitte um den eckigen Klammern enthalten sollte, und warum es durch befolgt werden müssen , eine der Befehlsliste Separatoren ( ;, &&, ||, |, &, Neue Zeile)

vladr
quelle
4
-list überflüssig, grepkehrt sofort zurück, wenn eine Übereinstimmung mit-q
Reinstate Monica Please
3

benutze einfach bash

while read -r line
do
  case "$line" in
    *MYSQL_ROLE=master*)
       echo "do your stuff";;
    *) echo "doesn't exist";;      
  esac
done <"/etc/aws/hosts.conf"
Ghostdog74
quelle