Bash
Bedingte Ausdrücke
Suche…
Syntax
- [[-OP $ Dateiname]]
- [[$ file1 -OP $ file2]]
- [[-z $ string]]
- [[-n $ string]]
- [["" $ string1 "==" $ string2 "]]]
- [["" $ string1 "== $ pattern]]
Bemerkungen
Die Syntax [[ … ]]
umgibt die eingebauten bedingten Ausdrücke von bash. Beachten Sie, dass auf beiden Seiten der Klammern Leerzeichen erforderlich sind.
Bedingte Ausdrücke können unäre und binäre Operatoren verwenden, um Eigenschaften von Strings, Ganzzahlen und Dateien zu testen. Sie können auch die logischen Operatoren &&
, ||
und !
.
Dateivergleich
if [[ $file1 -ef $file2 ]]; then
echo "$file1 and $file2 are the same file"
fi
"Gleiche Datei" bedeutet, dass die Änderung einer der vorhandenen Dateien die andere beeinflusst. Zwei Dateien können identisch sein, auch wenn sie unterschiedliche Namen haben, z. B. wenn es sich um feste Links handelt, oder wenn sie symbolische Links mit demselben Ziel sind oder wenn es sich bei einer der symbolischen Links um eine andere handelt.
Wenn zwei Dateien den gleichen Inhalt haben, es sich jedoch um unterschiedliche Dateien handelt (so dass die Änderung einer Datei sich nicht auf die andere auswirkt), werden sie von -ef
als unterschiedlich -ef
. Wenn Sie zwei Dateien byteweise vergleichen möchten, verwenden Sie das Dienstprogramm cmp
.
if cmp -s -- "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
echo "$file1 and $file2 differ"
fi
Verwenden Sie das Dienstprogramm diff
um eine von Menschen lesbare Liste der Unterschiede zwischen Textdateien zu erstellen.
if diff -u "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
: # the differences between the files have been listed
fi
Dateizugriffstests
if [[ -r $filename ]]; then
echo "$filename is a readable file"
fi
if [[ -w $filename ]]; then
echo "$filename is a writable file"
fi
if [[ -x $filename ]]; then
echo "$filename is an executable file"
fi
Diese Tests berücksichtigen Berechtigungen und Besitz, um zu bestimmen, ob das Skript (oder die vom Skript gestarteten Programme) auf die Datei zugreifen können.
Vorsicht vor den Rennbedingungen (TOCTOU) : Nur weil der Test jetzt erfolgreich ist, bedeutet das nicht, dass er in der nächsten Zeile noch gültig ist. In der Regel ist es besser, auf eine Datei zuzugreifen und den Fehler zu behandeln, anstatt zuerst zu testen und dann den Fehler trotzdem zu behandeln, falls sich die Datei in der Zwischenzeit geändert hat.
Numerische Vergleiche
Numerische Vergleiche verwenden die -eq
Operatoren und Freunde
if [[ $num1 -eq $num2 ]]; then
echo "$num1 == $num2"
fi
if [[ $num1 -le $num2 ]]; then
echo "$num1 <= $num2"
fi
Es gibt sechs numerische Operatoren:
-
-eq
gleich -
-ne
gleich -
-le
weniger oder gleich -
-lt
weniger als -
-ge
größer oder gleich -
-gt
größer als
Beachten Sie, dass die Operatoren <
und >
in [[ … ]]
Zeichenfolgen und nicht Zahlen vergleichen.
if [[ 9 -lt 10 ]]; then
echo "9 is before 10 in numeric order"
fi
if [[ 9 > 10 ]]; then
echo "9 is after 10 in lexicographic order"
fi
Die beiden Seiten müssen Dezimalzahlen (oder mit einer führenden Null in Oktal) sein. Verwenden Sie alternativ die ((…))
arithmetische Ausdruckssyntax, die Ganzzahlberechnungen in einer C / Java /… -ähnlichen Syntax durchführt.
x=2
if ((2*x == 4)); then
echo "2 times 2 is 4"
fi
((x += 1))
echo "2 plus 1 is $x"
Stringvergleich und Matching
Der Zeichenfolgenvergleich verwendet den Operator ==
zwischen den angegebenen Zeichenfolgen. Der Operator !=
Negiert den Vergleich.
if [[ "$string1" == "$string2" ]]; then
echo "\$string1 and \$string2 are identical"
fi
if [[ "$string1" != "$string2" ]]; then
echo "\$string1 and \$string2 are not identical"
fi
Wenn die rechte Seite nicht in Anführungszeichen steht, handelt es sich um ein Platzhaltermuster, mit dem $string1
verglichen wird.
string='abc'
pattern1='a*'
pattern2='x*'
if [[ "$string" == $pattern1 ]]; then
# the test is true
echo "The string $string matches the pattern $pattern"
fi
if [[ "$string" != $pattern2 ]]; then
# the test is false
echo "The string $string does not match the pattern $pattern"
fi
Die Operatoren <
und >
vergleichen die Zeichenfolgen in lexikographischer Reihenfolge (es gibt keine weniger oder gleich großen oder gleich großen Operatoren für Zeichenfolgen).
Es gibt unäre Tests für die leere Zeichenfolge.
if [[ -n "$string" ]]; then
echo "$string is non-empty"
fi
if [[ -z "${string// }" ]]; then
echo "$string is empty or contains only spaces"
fi
if [[ -z "$string" ]]; then
echo "$string is empty"
fi
Die -z
Prüfung kann bedeuten, dass $string
nicht gesetzt ist oder auf einen leeren String gesetzt ist. Um zwischen leeren und nicht gesetzten Werten zu unterscheiden, verwenden Sie:
if [[ -n "${string+x}" ]]; then
echo "$string is set, possibly to the empty string"
fi
if [[ -n "${string-x}" ]]; then
echo "$string is either unset or set to a non-empty string"
fi
if [[ -z "${string+x}" ]]; then
echo "$string is unset"
fi
if [[ -z "${string-x}" ]]; then
echo "$string is set to an empty string"
fi
wobei x
willkürlich ist. Oder in Tabellenform :
+-------+-------+-----------+
$string is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [[ -z ${string} ]] | true | true | false |
| [[ -z ${string+x} ]] | true | false | false |
| [[ -z ${string-x} ]] | false | true | false |
| [[ -n ${string} ]] | false | false | true |
| [[ -n ${string+x} ]] | false | true | true |
| [[ -n ${string-x} ]] | true | false | true |
+-----------------------+-------+-------+-----------+
Alternativ kann der Status in einer Case-Anweisung überprüft werden:
case ${var+x$var} in
(x) echo empty;;
("") echo unset;;
(x*[![:blank:]]*) echo non-blank;;
(*) echo blank
esac
Wobei [:blank:]
länderspezifische Zeichen für horizontalen Abstand (Tabulatorzeichen, Leerzeichen usw.)
Dateityp-Tests
Der Bedingungsoperator -e
prüft, ob eine Datei vorhanden ist (einschließlich aller Dateitypen: Verzeichnisse usw.).
if [[ -e $filename ]]; then
echo "$filename exists"
fi
Es gibt auch Tests für bestimmte Dateitypen.
if [[ -f $filename ]]; then
echo "$filename is a regular file"
elif [[ -d $filename ]]; then
echo "$filename is a directory"
elif [[ -p $filename ]]; then
echo "$filename is a named pipe"
elif [[ -S $filename ]]; then
echo "$filename is a named socket"
elif [[ -b $filename ]]; then
echo "$filename is a block device"
elif [[ -c $filename ]]; then
echo "$filename is a character device"
fi
if [[ -L $filename ]]; then
echo "$filename is a symbolic link (to any file type)"
fi
Bei einem symbolischen Link gelten diese Tests außer -L
für das Ziel und geben für einen unterbrochenen Link den Wert false zurück.
if [[ -L $filename || -e $filename ]]; then
echo "$filename exists (but may be a broken symbolic link)"
fi
if [[ -L $filename && ! -e $filename ]]; then
echo "$filename is a broken symbolic link"
fi
Test beim Beenden des Status eines Befehls
Ausgangsstatus 0: Erfolg
Exit-Status anders als 0: Fehler
So testen Sie den Beendigungsstatus eines Befehls:
if command;then
echo 'success'
else
echo 'failure'
fi
Ein Linientest
Sie können Dinge wie folgt machen:
[[ $s = 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s == 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s != 'something' ]] && echo "didn't match" || echo "matched"
[[ $s -eq 10 ]] && echo 'equal' || echo "not equal"
(( $s == 10 )) && echo 'equal' || echo 'not equal'
Ein Linientest für den Ausgangsstatus:
command && echo 'exited with 0' || echo 'non 0 exit'
cmd && cmd1 && echo 'previous cmds were successful' || echo 'one of them failed'
cmd || cmd1 #If cmd fails try cmd1