Die Shell-Syntax ist stark kontextabhängig. Das heißt, was für eine bestimmte Sache (wie true
oder false
) bedeutet, hängt stark davon ab, wo es auftritt. In Ihren Beispielen false
hat drei völlig unterschiedliche Bedeutungen:ein Befehl, ein Stringwert und ein (nicht vorhandener) Variablenname, der einen ganzzahligen Wert enthält. Lassen Sie mich die Beispiele durchgehen:
-
false
als Befehl:false; echo $? # prints "1" if false; then echo "yep"; else echo "nope"; fi # prints "nope"
Es gibt einen Befehl namens "false" (im Allgemeinen /usr/bin/false oder eine eingebaute Bash, die dasselbe tut), der nicht wirklich etwas tut, außer mit einem Fehlerstatus zu beenden. Als Exit-Status zeigt Null Erfolg an (was irgendwie wahr ist) und Nicht-Null zeigt Misserfolg an (was irgendwie falsch ist). Dies ist das Gegenteil der üblicheren Konvention null=falsch, ungleich null=wahr, aber für Exit-Status ist es sinnvoller.
-
false
als nicht interpretierter Zeichenfolgenwert:if [[ false ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ true ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ wibble ]]; then echo "yep"; else echo "nope"; fi # prints "yep" if [[ "this is a string" ]]; then echo "yep"; else echo "nope"; fi # prints "yep" [[ false ]]; echo $? # prints "0" (=success) [ false ]; echo $? # prints "0" (=success) test false; echo $? # prints "0" (=success)
In all diesen Fällen ist der Befehl
test
oder sein Synonym[
oder der bedingte Bash-Ausdruck[[ ]]
keinen Ausdruck erhalten, nur eine einzelne Zeichenfolge, also führen sie einen sehr einfachen Test durch:Ist es eine Zeichenfolge ungleich Null? "true", "false", "wibble" usw. haben alle eine Länge ungleich Null, daher ist der Befehl/Ausdruck wahrheitsähnlich und daher erfolgreich. Vergleichen Sie mit:[[ "" ]]; echo $? # prints "1" (=failure), because the string is zero-length [[ ]]; echo $? # prints "1" (=failure), because there isn't even a string [ ]; echo $? # same
Beachten Sie, dass
test
und[
sind normale Befehle, und "false" (und "wibble" usw.) ist nur ein Argument dafür.[[ ]]
ist ein bisschen Bash-Syntax, die anstelle eines Befehls verwendet werden kann. Ihre Argumente/Inhalte werden anders geparst als die Befehlsnamen selbst. -
false
als möglicher Variablenname, der eine Ganzzahl enthalten kann:if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # prints "equal"
Dieser hier ist etwas seltsamer und hängt von den Details von
[[ ]]
von bash ab Tests auf numerische Gleichheit. Beachten Sie das in[[ ]]
(und[ ]
undtest
Ausdrücke),-eq
Tests auf numerische Gleichheit und=
testet auf Zeichenkettengleichheit. Also zum Beispiel[[ 01 -eq 1 ]]
(weil 1 und 01 numerisch gleich sind) ist wahr, aber[[ 01 = 1 ]]
ist falsch (weil sie nicht dieselbe Zeichenfolge sind). Im Fall von[[ false -eq true ]]
, "true" und "false" sind keine ganzzahligen Werte, daher versucht bash, sie in ganze Zahlen umzuwandeln, indem sie sie als Variablennamen behandelt (und hofft, dass die Variablen ganzzahlige Werte enthalten). Tatsächlich ist keine von beiden als Variable definiert, sodass beide als leere Zeichenfolge ausgewertet werden, die als Ganzzahl 0 interpretiert werden kann. Beachten Sie:if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # prints "equal" if [[ false -eq 0 ]]; then echo "equal"; else echo "nope"; fi # prints "equal" false=5 if [[ false -eq true ]]; then echo "equal"; else echo "nope"; fi # now prints "nope"
Beachten Sie, dass
false
definiert wird als Variable hat keinen Einfluss auf seine anderen Verwendungen; Wenn es als Befehl verwendet wird, wird es immer noch mit Status 1 beendet, und wenn es als Zeichenfolge verwendet wird, ist es immer noch nur "false" (nicht "5").