So verwenden Sie bedingte Tests mit doppelten Klammern in Linux

Veröffentlicht: 2022-01-29
fatmawati achmad zaenuri/Shutterstock.com

Bedingte 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" 

Einfache Beispiele für den Bash-Testbefehl

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. */
Anzeige

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 $? 

Mit --help on test und [

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 [ 

Finden der verschiedenen Arten von [- und Testbefehlen

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
Anzeige

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.

Auflisten der Bash-Builtins

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 

Auflisten der Bash-Schlüsselwörter

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.

Anzeige

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 

Verwenden von chmod, um ein Skript ausführbar zu machen

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 

Ausführen des whelkie.sh-Skripts

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 

Ausführen des Skripts 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
Anzeige

Speichern Sie diese in einer Datei namens „Nachname.sh“ und machen Sie sie ausführbar. Führen Sie es aus mit:

 ./nachname.sh 

Ausführen des Skripts surname.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 

Ausführen des Skripts 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 

Ausführen des script.sh-Skripts

Anzeige

Bash wirft einen Fehler. Wir haben alle bis auf eine Skriptdatei entfernt und das Skript erneut ausgeführt.

 ls
 ./script.sh 

Ausführen des script.sh-Skripts mit einem einzelnen Skript im Verzeichnis

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 

Ausführen des dscript.sh-Skripts

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
Anzeige

Speichern Sie diesen Text in einer Datei namens „and.sh“, machen Sie ihn ausführbar und führen Sie ihn aus mit:

 ./und.sch 

Ausführen des and.sh-Skripts

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 

Ausführen des or.sh-Skripts

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 .

Anzeige

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 

Ausführen des regex.sh-Skripts

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.

Anzeige

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