Bearbeiten: Dies ist eine vollständigere Version, die mehr Unterschiede zwischen [
(aka test
) und zeigt [[
.
Die folgende Tabelle zeigt, dass -n/-z
es für die Überprüfung einer Variablen geeignet ist , ob eine Variable in Anführungszeichen gesetzt wird oder nicht, ob Sie einfache oder doppelte Klammern verwenden und ob die Variable nur ein Leerzeichen enthält .
| 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b
| [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"
-----+------------------------------------+------------------------------------
unset| false false true false true true | false false false false true true
null | false false true false true true | false false false false true true
space| false true true true true false| true true true true false false
zero | true true true true false false| true true true true false false
digit| true true true true false false| true true true true false false
char | true true true true false false| true true true true false false
hyphn| true true true true false false| true true true true false false
two | -err- true -err- true -err- false| true true true true false false
part | -err- true -err- true -err- false| true true true true false false
Tstr | true true -err- true -err- false| true true true true false false
Fsym | false true -err- true -err- false| true true true true false false
T= | true true -err- true -err- false| true true true true false false
F= | false true -err- true -err- false| true true true true false false
T!= | true true -err- true -err- false| true true true true false false
F!= | false true -err- true -err- false| true true true true false false
Teq | true true -err- true -err- false| true true true true false false
Feq | false true -err- true -err- false| true true true true false false
Tne | true true -err- true -err- false| true true true true false false
Fne | false true -err- true -err- false| true true true true false false
Wenn Sie wissen möchten, ob eine Variable eine Länge ungleich Null hat, führen Sie einen der folgenden Schritte aus:
- Geben Sie die Variable in Klammern an (Spalte 2a).
- Verwenden
-n
und zitieren Sie die Variable in einfachen Klammern (Spalte 4a).
- Verwenden Sie doppelte Klammern mit oder ohne Anführungszeichen und mit oder ohne
-n
(Spalten 1b - 4b)
Beachten Sie in Spalte 1a ab der Zeile mit der Bezeichnung "zwei", dass das Ergebnis angibt, dass [
der Inhalt der Variablen so ausgewertet wird, als ob er Teil des bedingten Ausdrucks wäre (das Ergebnis stimmt mit der Behauptung überein, die durch "T" oder "F" in impliziert wird die Beschreibungsspalte). Bei [[
Verwendung (Spalte 1b) wird der Variableninhalt als Zeichenfolge angezeigt und nicht ausgewertet.
Die Fehler in den Spalten 3a und 5a werden durch die Tatsache verursacht, dass der Variablenwert ein Leerzeichen enthält und die Variable nicht in Anführungszeichen steht. Wie in den Spalten 3b und 5b gezeigt, [[
wird der Inhalt der Variablen erneut als Zeichenfolge ausgewertet.
Entsprechend zeigen die Spalten 6a, 5b und 6b für Tests für Zeichenfolgen mit der Länge Null die richtigen Möglichkeiten, dies zu tun. Beachten Sie auch, dass jeder dieser Tests negiert werden kann, wenn das Negieren eine klarere Absicht zeigt als die Verwendung der entgegengesetzten Operation. Zum Beispiel : if ! [[ -n $var ]]
.
Wenn Sie verwenden [
, ist der Schlüssel, um sicherzustellen, dass Sie keine unerwarteten Ergebnisse erhalten, das Zitieren der Variablen. Verwenden [[
ist egal.
Die Fehlermeldungen, die unterdrückt werden, sind "unärer Operator erwartet" oder "binärer Operator erwartet".
Dies ist das Skript, das die obige Tabelle erstellt hat.
#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://stackoverflow.com/q/3869072
# designed to fit an 80 character terminal
dw=5 # description column width
w=6 # table column width
t () { printf '%-*s' "$w" " true"; }
f () { [[ $? == 1 ]] && printf '%-*s' "$w" " false" || printf '%-*s' "$w" " -err-"; }
o=/dev/null
echo ' | 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b'
echo ' | [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"'
echo '-----+------------------------------------+------------------------------------'
while read -r d t
do
printf '%-*s|' "$dw" "$d"
case $d in
unset) unset t ;;
space) t=' ' ;;
esac
[ $t ] 2>$o && t || f
[ "$t" ] && t || f
[ -n $t ] 2>$o && t || f
[ -n "$t" ] && t || f
[ -z $t ] 2>$o && t || f
[ -z "$t" ] && t || f
echo -n "|"
[[ $t ]] && t || f
[[ "$t" ]] && t || f
[[ -n $t ]] && t || f
[[ -n "$t" ]] && t || f
[[ -z $t ]] && t || f
[[ -z "$t" ]] && t || f
echo
done <<'EOF'
unset
null
space
zero 0
digit 1
char c
hyphn -z
two a b
part a -a
Tstr -n a
Fsym -h .
T= 1 = 1
F= 1 = 2
T!= 1 != 2
F!= 1 != 1
Teq 1 -eq 1
Feq 1 -eq 2
Tne 1 -ne 2
Fne 1 -ne 1
EOF
["
vs[-n"
(die erste Frage des OP) zeigt also, dass sie völlig gleichwertig sind, oder?[["
Es ist besser , das zu verwenden , leistungsfähigeren
[[
bis Bash betrifft.Übliche Fälle
Die beiden obigen Konstrukte sehen sauber und lesbar aus. Sie sollten in den meisten Fällen ausreichen.
Beachten Sie, dass wir die Variablenerweiterungen im Inneren nicht zitieren müssen,
[[
da keine Gefahr der Wortteilung und des Globbing besteht .Um die weichen Beschwerden von Shellcheck über
[[ $var ]]
und zu vermeiden[[ ! $var ]]
, könnten wir die-n
Option verwenden.Seltene Fälle
In dem seltenen Fall, dass wir zwischen "auf eine leere Zeichenfolge gesetzt" und "überhaupt nicht gesetzt" unterscheiden müssen, könnten wir diese verwenden:
Wir können den
-v
Test auch verwenden :Verwandte Beiträge und Dokumentation
Es gibt viele Beiträge zu diesem Thema. Hier sind ein paar:
[[
vs spricht[
[
vs.[[
quelle
Hier sind einige weitere Tests
True, wenn der String nicht leer ist:
True, wenn die Zeichenfolge leer ist:
quelle
Die richtige Antwort lautet wie folgt:
Beachten Sie die Verwendung von
[[...]]
, die das Zitieren der Variablen für Sie korrekt handhabt.quelle
-n
wenn es in Bash nicht wirklich benötigt wird?Eine alternative und möglicherweise transparentere Methode zur Bewertung einer leeren Umgebungsvariablen ist die Verwendung von ...
quelle
bash
ist ein schärferes Werkzeug als seine Vorgänger.[ "$ENV_VARIABLE" != "" ]
funktioniert auf jeder Shell mit einer POSIX-kompatiblentest
Implementierung - nicht nur bash, sondern ash / dash / ksh / etc.-a
oder-o
kombinieren Sie keine Tests, sondern verwenden Sie[ ... ] && [ ... ]
oder[ ... ] || [ ... ]
und die einzigen Eckfälle, die für die Verwendung der Daten beliebiger Variablen in einem Test gelten können, sind eindeutig geschlossen.Verwenden Sie
case/esac
zum Test:quelle
case
gedacht.case
funktioniert am besten, wenn es mehr als zwei Alternativen gibt.case
ist nicht für diese Art der Verwendung vorgesehen.