So verwenden Sie bedingte Tests mit doppelten Klammern in Linux
Veröffentlicht: 2022-01-29Bedingte Tests verzweigen den Ausführungsfluss von Linux-Bash-Skripten entsprechend dem Ergebnis eines logischen Ausdrucks. Bedingte Tests mit doppelten Klammern vereinfachen die Syntax erheblich – haben aber immer noch ihre eigenen Fallstricke.
Einfache und doppelte Klammern
Bash stellt den test
bereit. Damit können Sie logische Ausdrücke testen. Der Ausdruck gibt eine Antwort zurück, die eine wahre oder falsche Antwort anzeigt. Eine wahre Antwort wird durch einen Rückgabewert von Null angezeigt. Alles andere als Null zeigt falsch an.
Das Verketten von Befehlen in der Befehlszeile mit dem Operator &&
verwendet diese Funktion. Befehle werden nur ausgeführt, wenn der vorherige Befehl erfolgreich abgeschlossen wurde.
Wenn der Test wahr ist, wird das Wort „Ja“ gedruckt.
test 15 -eq 15 && echo "Ja"
test 14 -eq 15 && echo "Ja"
Die Bedingungstests mit einer Klammer ahmen den test
nach. Sie schließen den Ausdruck in eckige Klammern „ [ ]
“ ein und funktionieren genauso wie der test
. Tatsächlich handelt es sich um dasselbe Programm, das aus demselben Quellcode erstellt wurde. Der einzige betriebliche Unterschied besteht darin, wie die test
und die [
-Version Hilfeanfragen behandeln.
Das ist aus dem Quellcode:
/* Erkenne --help oder --version, aber nur, wenn es in der aufgerufen wird "["-Form, wenn das letzte Argument nicht "]" ist. Direkt verwenden parsing statt parse_long_options, um ein Akzeptieren zu vermeiden Abkürzungen. POSIX erlaubt "[ --help" und "[ --version" zu haben das übliche GNU-Verhalten, aber es erfordert "test --help" und "test --version", um still mit Status 0 zu beenden. */
Wir können die Auswirkung davon sehen, indem wir test
und [
um Hilfe bitten und den an Bash gesendeten Antwortcode überprüfen.
testen - Hilfe
Echo $?
[ --Hilfe
Echo $?
Sowohl test
als auch [
sind Shell builtins , was bedeutet, dass sie direkt in Bash integriert sind. Aber es gibt auch eine eigenständige Binärversion von [
.
Typprüfung
Typ [
wo ist [
Im Gegensatz dazu sind die Bedingungstests mit zwei Klammern [[
und ]]
Schlüsselwörter . [[
und ]]
führen auch logische Tests durch, aber ihre Syntax ist anders. Da es sich um Schlüsselwörter handelt, können Sie einige nette Funktionen verwenden, die in der Version mit einer Klammer nicht funktionieren.
Die Schlüsselwörter mit doppelten Klammern werden von Bash unterstützt, sind aber nicht in jeder anderen Shell verfügbar. Beispielsweise werden sie von der Korn-Shell unterstützt, von der einfachen alten Shell sh jedoch nicht. Alle unsere Skripte beginnen mit der Zeile:
#!/bin/bash
Dadurch wird sichergestellt, dass wir die Bash-Shell aufrufen, um das Skript auszuführen.
VERWANDT: Erstellen und Ausführen von Bash-Shell-Skripts unter Windows 10
Builtins und Schlüsselwörter
Wir können das Programm compgen verwenden, um die compgen
aufzulisten:
compgen -b | fmt -w 70
Ohne die Ausgabe durch fmt
zu leiten, würden wir eine lange Liste erhalten, in der jedes Builtin in einer eigenen Zeile steht. In diesem Fall ist es bequemer, die Builtins in einem Absatz gruppiert zu sehen.
Wir können test
und [
in der Liste sehen, aber ]
ist nicht aufgeführt. Der [
Befehl sucht nach einem schließenden ]
, um zu erkennen, wann er das Ende des Ausdrucks erreicht hat, aber ]
ist kein separates Builtin. Es ist nur ein Signal, das wir an [
geben, um das Ende der Parameterliste anzuzeigen.
Um die Schlüsselwörter zu sehen, können wir Folgendes verwenden:
compgen -k | fmt -w 70
Die Schlüsselwörter [[
und ]]
befinden sich beide in der Liste, da [[
ein Schlüsselwort und ]]
ein anderes ist. Sie sind ein passendes Paar, genau wie if
und fi
und case
und esac
.
Wenn Bash ein Skript – oder eine Befehlszeile – parst und ein Schlüsselwort erkennt, das ein passendes, schließendes Schlüsselwort hat, sammelt es alles, was dazwischen erscheint, und wendet die spezielle Behandlung an, die die Schlüsselwörter unterstützen.
Bei einem eingebauten Befehl wird das, was auf den eingebauten Befehl folgt, genau wie Parameter an jedes andere Befehlszeilenprogramm übergeben. Das bedeutet, dass der Autor des Skripts besondere Sorgfalt auf solche Dinge wie Leerzeichen in Variablenwerten verwenden muss.
Shell Globbing
Bedingte Tests mit zwei Klammern können Shell Globbing verwenden. Das bedeutet, dass das Sternchen „ *
“ erweitert wird, um „alles“ zu bedeuten.
Geben oder kopieren Sie den folgenden Text in einen Editor und speichern Sie ihn in einer Datei namens „whelkie.sh“.
#!/bin/bash stringvar="Whelkie Brookes" if [[ "$stringvar" == *elk* ]]; dann Echo "Warnung enthält Meeresfrüchte" anders Echo "Ohne Weichtiere" fi
Um das Skript ausführbar zu machen, müssen wir den Befehl chmod
mit der Option -x
(Ausführen) verwenden. Sie müssen dies für alle Skripte in diesem Artikel tun, wenn Sie sie ausprobieren möchten.
chmod +x whelkie.sh
Wenn wir das Skript ausführen, sehen wir, dass die Zeichenfolge „elk“ in der Zeichenfolge „Whelkie“ gefunden wurde, unabhängig davon, welche anderen Zeichen sie umgeben.
./whelkie.sh
Beachten Sie, dass wir die Suchzeichenfolge nicht in doppelte Anführungszeichen setzen. Wenn Sie dies tun, wird das Globbing nicht passieren. Der Suchstring wird wörtlich behandelt.
Andere Formen des Shell Globbing sind erlaubt. Das Fragezeichen „ ?
“ stimmt mit einzelnen Zeichen überein, und einzelne eckige Klammern werden verwendet, um Zeichenbereiche anzugeben. Wenn Sie beispielsweise nicht wissen, welchen Fall Sie verwenden sollen, können Sie beide Eventualitäten mit einem Bereich abdecken.
#!/bin/bash stringvar="Jean-Claude van Clam" if [[ "$stringvar" == *[cC]lam* ]]; dann echo "Warnung enthält Meeresfrüchte." anders echo "Ohne Weichtiere." fi
Speichern Sie dieses Skript als „damme.sh“ und machen Sie es ausführbar. Wenn wir es ausführen, löst sich die bedingte Anweisung in wahr auf und die erste Klausel der if-Anweisung wird ausgeführt.
./damme.sh
Strings zitieren
Wir haben bereits erwähnt, dass Strings in doppelte Anführungszeichen gesetzt werden. Wenn Sie dies tun, tritt kein Shell Globbing auf. Obwohl die Konvention sagt, dass es eine gute Praxis ist, müssen Sie String-Variablen nicht in Anführungszeichen setzen, wenn Sie [[
und ]]
verwenden, selbst wenn sie Leerzeichen enthalten. Sehen Sie sich das nächste Beispiel an. Sowohl die String-Variablen $stringvar
als auch $surname
surname enthalten Leerzeichen, aber keine davon wird in der bedingten Anweisung in Anführungszeichen gesetzt.
#!/bin/bash stringvar="van Damme" Nachname = "van Damme" if [[ $stringvar == $nachname ]]; dann echo "Nachnamen stimmen überein." anders echo "Nachnamen stimmen nicht überein." fi
Speichern Sie diese in einer Datei namens „Nachname.sh“ und machen Sie sie ausführbar. Führen Sie es aus mit:
./nachname.sh
Obwohl beide Zeichenfolgen Leerzeichen enthalten, ist das Skript erfolgreich und die bedingte Anweisung wird zu wahr aufgelöst. Dies ist nützlich, wenn Sie mit Pfaden und Verzeichnisnamen umgehen, die Leerzeichen enthalten. Hier gibt die Option -d
true zurück, wenn die Variable einen gültigen Verzeichnisnamen enthält.
#!/bin/bash dir="/home/dave/Documents/Benötigt Arbeit" wenn [[ -d ${dir} ]]; dann echo "Verzeichnis bestätigt" anders Echo "Verzeichnis nicht gefunden" fi
Wenn Sie den Pfad im Skript so ändern, dass er ein Verzeichnis auf Ihrem eigenen Computer widerspiegelt, den Text in einer Datei namens „dir.sh“ speichern und ausführbar machen, können Sie sehen, dass dies funktioniert.
./dir.sh
VERWANDT: So arbeiten Sie mit Variablen in Bash
Dateiname Globbing Gotchas
Ein interessanter Unterschied zwischen [ ]
und [[ ]]
bezieht sich auf Dateinamen mit Globbing darin. Die Form „*.sh“ stimmt mit allen Skriptdateien überein. Die Verwendung einfacher Klammern [ ]
schlägt fehl, es sei denn, es gibt eine einzelne Skriptdatei. Wenn Sie mehr als ein Skript finden, wird ein Fehler ausgegeben.
Hier ist das Skript mit Bedingungen in einzelnen Klammern.
#!/bin/bash wenn [ -a *.sh ]; dann echo "Skriptdatei gefunden" anders echo "Keine Skriptdatei gefunden" fi
Diesen Text haben wir in „script.sh“ gespeichert und ausführbar gemacht. Wir haben überprüft, wie viele Skripte sich im Verzeichnis befinden, und dann das Skript ausgeführt.
ls
./script.sh
Bash wirft einen Fehler. Wir haben alle bis auf eine Skriptdatei entfernt und das Skript erneut ausgeführt.
ls
./script.sh
Der bedingte Test gibt wahr zurück und das Skript verursacht keinen Fehler. Das Bearbeiten des Skripts zur Verwendung von doppelten Klammern bietet eine dritte Art von Verhalten.
#!/bin/bash wenn [[ -a *.sh ]]; dann echo "Skriptdatei gefunden" anders echo "Keine Skriptdatei gefunden" fi
Diese haben wir in einer Datei namens „dscript.sh“ gespeichert und ausführbar gemacht. Wenn Sie dieses Skript in einem Verzeichnis mit vielen Skripts ausführen, wird kein Fehler ausgegeben, aber das Skript erkennt keine Skriptdateien.
Die bedingte Anweisung mit doppelten Klammern wird nur in dem unwahrscheinlichen Fall wahr, dass Sie tatsächlich eine Datei mit dem Namen „*.sh“ im Verzeichnis haben.
./dscript.sh
Logisches UND und ODER
Mit doppelten Klammern können Sie &&
und ||
verwenden als die logischen UND- und ODER-Operatoren.
Dieses Skript sollte die bedingte Anweisung als wahr auflösen, da 10 gleich 10 und 25 kleiner als 26 ist.
#!/bin/bash erste = 10 Sekunde = 25 if [[ first -eq 10 && second -lt 26 ]]; dann echo "Bedingung erfüllt" anders echo "Bedingung fehlgeschlagen" fi
Speichern Sie diesen Text in einer Datei namens „and.sh“, machen Sie ihn ausführbar und führen Sie ihn aus mit:
./und.sch
Das Skript wird wie erwartet ausgeführt.
Dieses Mal verwenden wir das ||
Operator. Die bedingte Anweisung sollte wahr werden, denn obwohl 10 nicht größer als 15 ist, ist 25 immer noch kleiner als 26. Solange entweder der erste Vergleich oder der zweite Vergleich wahr ist, wird die bedingte Anweisung als Ganzes zu wahr aufgelöst.
Speichern Sie diesen Text als „or.sh“ und machen Sie ihn ausführbar.
#!/bin/bash erste = 10 Sekunde = 25 if [[ zuerst -gt 15 || zweites -lt 26 ]]; dann echo "Bedingung erfüllt." anders echo "Bedingung fehlgeschlagen." fi
./oder.sch
Regexe
Bedingte Anweisungen mit doppelten Klammern erlauben die Verwendung des Operators =~
, der die Regex-Suchmuster in einer Zeichenfolge auf die andere Hälfte der Anweisung anwendet. Wenn die Regex erfüllt ist, wird die bedingte Anweisung als wahr angesehen. Wenn die Regex keine Übereinstimmungen findet, wird die bedingte Anweisung zu „false“ aufgelöst.
VERWANDT: So verwenden Sie reguläre Ausdrücke (Regexes) unter Linux
Speichern Sie diesen Text in einer Datei namens „regex.sh“ und machen Sie sie ausführbar.
#!/bin/bash Wörter = "eins zwei drei" WordsandNumbers="eins 1 zwei 2 drei 3" email="[email protected]" mask1="[0-9]" mask2="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}" if [[ $words =~ $mask1 ]]; dann echo "\"$words\" enthält Ziffern." anders echo "Keine Ziffern in \"$words\" gefunden." fi if [[ $WörterundZahlen =~ $mask1 ]]; dann echo "\"$WörterundZahlen\" enthält Ziffern." anders echo "Keine Ziffern in \"$WordsandNumbers\" gefunden." fi if [[ $email =~ $mask2 ]]; dann echo "\"$email\" ist eine gültige E-Mail-Adresse." anders echo "Konnte \"$email\" nicht parsen." fi
Der erste Satz doppelter Klammern verwendet die Zeichenfolgenvariable $mask1
als Regex. Dieses enthält das Muster für alle Ziffern im Bereich von null bis neun. Es wendet diese Regex auf die Zeichenfolgenvariable $words
an.
Der zweite Satz doppelter Klammern verwendet erneut die String-Variable $mask1
als Regex, diesmal jedoch mit der String-Variable $WordsandNumbers
.
Der letzte Satz doppelter Klammern verwendet eine komplexere Regex-Maske in der Zeichenfolgenvariablen $mask2
.
- [A-Za-z0-9._%+-]+ : Dies entspricht jedem Zeichen, das ein Groß- oder Kleinbuchstabe oder eine Ziffer von null bis neun oder ein Punkt, Unterstrich, Prozentzeichen oder Plus- oder Minuszeichen ist . Das „
+
“ außerhalb des „[]
“ bedeutet, dass diese Übereinstimmungen für so viele Zeichen wiederholt werden, wie es findet. - @ : Dies stimmt nur mit dem Zeichen „@“ überein.
- [A-Za-z0-9.-]+ : Dies entspricht jedem Zeichen, das ein Groß- oder Kleinbuchstabe, eine beliebige Ziffer von null bis neun, ein Punkt oder ein Bindestrich ist. Das „
+
“ außerhalb des „[ ]
“ bedeutet, dass diese Übereinstimmungen für so viele Zeichen wiederholt werden, wie es findet. - . : Dies entspricht dem „.“ nur Charakter.
- [A-Za-z]{2,4} : Dies entspricht jedem Groß- oder Kleinbuchstaben. Das „
{2,4}
“ bedeutet Übereinstimmung mit mindestens zwei und höchstens vier Zeichen.
Alles in allem prüft die Regex-Maske, ob eine E-Mail-Adresse korrekt gebildet ist.
Speichern Sie den Skripttext in einer Datei namens „regex.sh“ und machen Sie ihn ausführbar. Wenn wir das Skript ausführen, erhalten wir diese Ausgabe.
./regex.sh
Die erste bedingte Anweisung schlägt fehl, weil die Regex nach Ziffern sucht, der Wert in der Zeichenfolgenvariablen „ $words
“ jedoch keine Ziffern enthält.
Die zweite bedingte Anweisung ist erfolgreich, da die Zeichenfolgenvariable $WordsandNumbers
Ziffern enthält.
Die letzte bedingte Anweisung ist erfolgreich – das heißt, sie wird zu wahr aufgelöst – weil die E-Mail-Adresse richtig formatiert ist.
Nur eine Bedingung
Bedingte Tests mit zwei Klammern verleihen Ihren Skripten Flexibilität und Lesbarkeit. Nur in der Lage zu sein, reguläre Ausdrücke in Ihren bedingten Tests zu verwenden, rechtfertigt das Erlernen der Verwendung von [[
and ]]
.
Stellen Sie einfach sicher, dass das Skript eine Shell aufruft, die sie unterstützt, wie Bash.
VERBINDUNG: 15 Sonderzeichen, die Sie für Bash kennen müssen