Antworten:
Einzelne eckige Klammern in der Shell sind ein Synonym für test
(entweder der separate Befehl oder die integrierte Shell) und [ 0 ]
bedeuten dasselbe wie test 0
. test
dient zum Vergleichen und Testen der Attribute von Dateien, wie Sie in der Manpage lesen können. Wenn es keinen Ausdruck gibt, der aussieht wie ein Vergleich, ein Dateitest oder eine der anderen Operationen, die es ausführen kann, wird stattdessen geprüft, ob das Argument vorhanden ist und eine nicht leere Zeichenfolge. Weder 0
noch 1
sind wirklich geeignete Eingaben für den Test, und als nicht leere Zeichenfolgen ist der Test einfach erfolgreich, und Ihre while-Schleife wird für immer wiederholt.
Vielleicht möchten Sie es stattdessen versuchen
while false; do
echo "hello"
done
möglicherweise ersetzen false
durch true
. Oder vielleicht möchten Sie Folgendes verwenden (( ))
:
while (( 0 )); do
echo "hello"
done
Was sich wie die meisten Sprachen verhält, wobei 0 Fehlschlag / Falsch und 1 Erfolg / Wahr bedeutet.
0
und 1
keine leeren Zeichenfolgen sind. Neue Shell-Programmierer schreiben oft if [ 1=2 ]
anstatt if [ 1 = 2 ]
und fragen sich, warum das erstere immer wahr ist. Es ist wahr, weil es ein einzelnes Argument und keine leere Zeichenfolge ist.
Der Wert 0 wirkt hier nicht als numerische Konstante, sondern als Zeichenkette. Diese Tests haben alle die gleiche Wirkung auf einen erfolgreichen Kündigungsstatus:
[ A ]
[ "XYZ" ]
[ 0 ]
Diese führen zu einem fehlgeschlagenen Beendigungsstatus:
[ ]
[ "" ]
Es gibt ein nicht leeres Argument, das als logisch wahr ausgewertet wird. Auf diese Weise können Sie folgende Aufgaben ausführen:
if [ $UNDER_NUCLEAR_ATTACK ] ; then
launch-missiles -a $DRY_RUN # $DRY_RUN set to "-n" during testing
fi
Die Variable UNDER_NUCLEAR_ATTACK
wird auf einen beliebigen nicht leeren Wert gesetzt, um "wahr" anzuzeigen, oder ist nicht gesetzt oder leer, um "falsch" anzuzeigen.
Wir können den !
Operator anwenden , um die Logik umzukehren:
[ ! a ] # fails: a is nonblank so true; and not true is false.
[ ! ] # succeeds: blank is false, not blank is true.
Um eine numerische Bedingung auszuwerten, müssen Sie numerische Testoperatoren verwenden:
while [ $A -gt $B ] ; do ...
Wenn A
und B
Zeichenfolgen enthalten, die wie Dezimalzahlen aussehen, werden sie wie Zahlen verglichen, und wenn A
größer als B
, wird die Schleife ausgeführt. Nehmen wir also an, dies UNDER_NUCLEAR_ATTACK
ist kein Boolescher Wert vom Typ String, der leer oder nicht leer ist, sondern ein numerischer Boolescher 0
Wert , der entweder (false) oder ein anderer Wert (true) ist. In diesem Fall würden wir den Test folgendermaßen schreiben:
if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...
Ein if / then-Konstrukt testet, ob der Beendigungsstatus einer Befehlsliste 0 ist (da 0 gemäß UNIX-Konvention "Erfolg" bedeutet), und führt in diesem Fall einen oder mehrere Befehle aus.
Kurz gesagt, Sie geben ein Testergebnis von Null zurück.
[
nur ein Argument abgerufen ]
wird (natürlich ohne das ), wird es mit dem Status Null beendet, wenn das Argument nicht leer ist, und wenn es nicht null ist. So wird beispielsweise [ 1 ]
auch ein Exit-Code von zurückgegeben 0
.
Der Wert 0 gilt als wahr für die while-Schleife, daher ist die Bedingung für while-Schleife wahr und daher stetig, um die Endlosschleife anzuzeigen. Das ist wahr, wenn wir 0 durch 1 ersetzen, da jede ganze Zahl, die wir zwischen die Bedingung schreiben, true zurückgibt
[ ]
(ohne Argument) und[ "" ]
(mit einem einzigen leeren Argument) nicht erfolgreich.