Bedingte Ausdrücke in der Bash-Shell
Bash als Programmiersprache ist für die meisten Programmierer nicht die erste Wahl, insbesondere bei weitaus verbreiteteren Sprachen wie Python und C.
Es ist hilfreich, Programmierkonstrukte zu schreiben, um Befehle basierend auf Kriterien mit if-Anweisungen oder denselben Befehl mit mehreren Argumenten unter Verwendung einer for
-Schleife auszuführen.
Dieses Tutorial geht auf if-Anweisungen in Bash ein und konzentriert sich auf die Arten von bedingten Ausdrücken, die in if-Anweisungen verwendet werden.
Die if
-Anweisung in Bash
Die allgemeine Syntax der if
-Anweisung in Bash ist wie folgt.
if condition; then
do-if-true;
elif second-condition; then
do-else-if-true
elif third-condition; then
do-else-if-third-true
else
do-else-false
fi
Die Bedingungen selbst können je nach erforderlicher Bedingung unterschiedliche Syntax haben.
- Wenn Sie die Ausgabe eines Befehls als Bedingung verwenden möchten, z. B.
grep
den Inhalt einer Datei, um zu sehen, ob sie einen bestimmten Teilstring enthält, können Sie den Befehl wie folgt nach dem Schlüsselwort if platzieren.
if greq -q "string" file.txt; then
echo "string exists in file.txt."
else
echo "string does not exist in file.txt."
fi
[ "$s" = "string" ]
prüft, ob die Variable$s
den Wertstring
enthält. Es ist auch äquivalent zutest "$s" = "string"
, wobeitest
effektiv die eckigen Klammern ersetzt.
if [ "$s" = "string" ]; then
echo "string is equivalent to \$s"
else
echo "string is not equivalent to \$s"
fi
-
Sie können sogar Rechenoperationen durchführen, zB überprüfen, ob die erwartete Anzahl von Dateien oder Zeilen in einer Datei sicher ist oder ob die Anzahl in einem Verzeichnis kleiner oder größer als die eines anderen Verzeichnisses ist.
Wir tun dies mit Paaren von Klammern.
a=$(ls dir_a | wc -l)
b=$(ls dir_b | wc -l)
if (( a < b )); then
echo "Directory a has fewer files than directory b."
elif (( a > b )); then
echo "Directory a has more files than directory b."
else
echo "Directory a has the same number of files as that of directory b."
fi
Eingebaute Bash-Bedingungen
Manchmal ist es mühsam und ressourcenintensiv, ein separates Programm auszuführen, um etwas so Einfaches wie das Vorhandensein von Dateien, Änderungsdaten und -größen zu überprüfen, sodass Bash solche Attribute wie if-Anweisungen direkt überprüfen kann.
Die folgenden Flags prüfen, ob diese Attribute vorhanden oder nicht vorhanden sind, und geben ein effektiv wahres oder falsches Ergebnis an die if-Anweisung zurück.
Um beispielsweise zu überprüfen, ob ein Befehl keine Ausgabe erzeugt hat, können wir seine Ausgabe als Zeichenfolge behandeln und mit dem Flag -z
wie folgt prüfen, ob die Länge dieser Zeichenfolge Null ist.
out=$(bash print-if-error.sh)
if [[ -z $out ]]; then
echo "The script ran successfully."
else
echo "The script produced the following errors: "
echo $out
fi
Um die Umkehrung der Bedingung zu erhalten, können Sie entweder das !
NOT-Operator, oder verwenden Sie die umgekehrte Form dieses Flags, die entweder -n
oder überhaupt kein Flag ist, da sich eine nicht leere Zeichenfolge in einer Bash-if-Anweisung als true
verhalten kann.
out=$(bash print-if-error.sh)
if [[ $out ]]; then
echo "The script produced the following errors: "
echo $out
else
echo "The script ran successfully."
fi
Einige andere nützliche Flags werden unten erläutert, wobei auf Erläuterungen aus dem GNU Bash Reference Manual verwiesen wird.
-f
prüft, ob die Datei existiert und ob es sich um eine normale Datei handelt.-d
prüft, ob das angegebene Argument ein Verzeichnis war.-h
prüft, ob das angegebene Argument ein symbolischer Link war.-s
prüft, ob die Datei existiert und nicht leer ist.-r
prüft, ob die Datei lesbar ist.-w
prüft, ob die Datei beschreibbar ist.-x
prüft, ob die Datei ausführbar ist.
Bei Flags, die zwei Argumente annehmen, wie z. B. Vergleichsoperatoren, steht das erste Argument vor dem Flag, während das zweite hinter dem Flag steht.
Angenommen, wir vergleichen zwei Dateien – a.txt und b.txt – um zu sehen, welche neuer ist, mit dem Flag -nt
. Umgekehrt wird mit -ot
geprüft, ob es älter ist.
out=$(bash print-if-error.sh)
if [[ a.txt -nt b.txt ]]; then
echo "a.txt is newer than b.txt."
else
echo "a.txt is older or the same age as b.txt."
fi
Andere solche Zwei-Operanden-Flags sind wie folgt.
-ef
stellt sicher, dass sich die beiden Argumente auf dieselben Geräte- und Inode-Nummern beziehen.!=
stellt sicher, dass die beiden Argumente nicht gleich sind.<
prüft, ob das erste Argument alphabetisch vor dem zweiten steht.>
prüft, ob das erste Argument alphabetisch nach dem zweiten steht.-eq
geht davon aus, dass beide Argumente ganze Zahlen sind und prüft, ob sie gleich sind.-ne
geht davon aus, dass beide Argumente ganze Zahlen sind und prüft, ob sie ungleich sind.-lt
geht davon aus, dass beide Argumente ganze Zahlen sind und prüft, ob das erste kleiner als das zweite ist. Man kann mit-le
prüfen, ob sie gleich sind.-gt
geht davon aus, dass beide Argumente ganze Zahlen sind und prüft, ob das erste größer als das zweite ist. Man kann mit-ge
prüfen, ob sie gleich sind.