Hier scheint es ein Missverständnis über das eingebaute Bash zu geben true
, und insbesondere darüber, wie Bash Ausdrücke in Klammern erweitert und interpretiert.
Der Code in Mikus Antwort hat absolut nichts mit dem eingebauten Bash zu tun true
, noch /bin/true
mit irgendeiner anderen Variante des true
Befehls. In diesem Fall true
handelt es sich true
lediglich um eine einfache Zeichenfolge, und es wird niemals ein Aufruf des Befehls / der eingebauten Datei vorgenommen, weder durch die Variablenzuweisung noch durch die Auswertung des bedingten Ausdrucks.
Der folgende Code ist funktional identisch mit dem Code in der Antwort des Mikus:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
Der einzige Unterschied besteht darin, dass die vier verglichenen Zeichen 'y', 'e', 'a' und 'h' anstelle von 't', 'r', 'u' und 'e' sind. Das ist es. Es wird weder versucht, einen Befehl oder ein eingebautes Objekt mit dem Namen aufzurufen yeah
, noch wird (in Mikus Beispiel) irgendeine spezielle Behandlung ausgeführt, wenn Bash das Token analysiert true
. Es ist nur eine Saite und eine völlig willkürliche.
Update (2014-02-19): Nachdem ich dem Link in Mikus Antwort gefolgt bin, sehe ich jetzt, woher ein Teil der Verwirrung kommt. Mikus Antwort verwendet einzelne Klammern, aber das Code-Snippet, mit dem er verknüpft ist, verwendet keine Klammern. Es ist nur:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
Beide Codefragmente verhalten sich gleich, aber die Klammern ändern vollständig, was unter der Haube vor sich geht.
Hier ist, was Bash in jedem Fall tut:
Keine Klammern:
- Erweitern Sie die Variable
$the_world_is_flat
auf die Zeichenfolge "true"
.
- Versuchen Sie, die Zeichenfolge
"true"
als Befehl zu analysieren .
- Suchen Sie den
true
Befehl und führen Sie ihn aus (entweder integriert oder /bin/true
abhängig von der Bash-Version).
- Vergleichen Sie den Exit-Code des
true
Befehls (der immer 0 ist) mit 0. Denken Sie daran, dass in den meisten Shells ein Exit-Code von 0 Erfolg anzeigt und alles andere einen Fehler anzeigt.
- Da der Exit-Code 0 (Erfolg) war, führen Sie die Klausel der
if
Anweisung austhen
Klammern:
- Erweitern Sie die Variable
$the_world_is_flat
auf die Zeichenfolge "true"
.
- Analysieren Sie den jetzt vollständig erweiterten bedingten Ausdruck, der die Form hat
string1 = string2
. Der =
Operator ist der String-Vergleichsoperator von bash . Damit...
- Führen Sie einen Zeichenfolgenvergleich für
"true"
und durch "true"
.
- Ja, die beiden Zeichenfolgen waren gleich, daher ist der Wert der Bedingung wahr.
- Führen Sie die Klausel der
if
Anweisung aus then
.
Der Code ohne Klammern funktioniert, da der true
Befehl einen Exit-Code von 0 zurückgibt, der den Erfolg anzeigt. Der Code in Klammern funktioniert, da der Wert von $the_world_is_flat
mit dem Zeichenfolgenliteral true
auf der rechten Seite von identisch ist =
.
Betrachten Sie die folgenden zwei Codeausschnitte, um den Punkt nach Hause zu bringen:
Dieser Code (wenn er mit Root-Rechten ausgeführt wird) startet Ihren Computer neu:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
Dieser Code gibt nur "Netter Versuch" aus. Der Neustartbefehl wird nicht aufgerufen.
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
Update (14.04.2014) Um die Frage in den Kommentaren zum Unterschied zwischen =
und ==
: AFAIK zu beantworten , gibt es keinen Unterschied. Der ==
Operator ist ein Bash-spezifisches Synonym für =
und soweit ich gesehen habe, funktionieren sie in allen Kontexten genau gleich.
Beachten Sie jedoch, dass ich speziell über die Vergleichs- =
und ==
Zeichenfolgenvergleichsoperatoren spreche, die entweder in [ ]
oder in [[ ]]
Tests verwendet werden. Ich schlage das nicht vor =
und bin überall in Bash ==
austauschbar .
Zum Beispiel können Sie offensichtlich keine Variablenzuweisung durchführen ==
, wie zum Beispiel var=="foo"
(technisch gesehen können Sie dies tun, aber der Wert von var
wird sein "=foo"
, da Bash hier keinen ==
Operator sieht , sondern einen =
(Zuweisungs-) Operator, gefolgt von der wörtliche Wert ="foo"
, der gerade wird "=foo"
).
Auch, obwohl =
und ==
untereinander austauschbar sind, sollten Sie bedenken , dass , wie diese Tests Arbeit nicht davon ab , ob Sie es innen mit sind [ ]
oder [[ ]]
, und auch davon , ob oder nicht die Operanden angegeben. Weitere Informationen hierzu finden Sie im Advanced Bash Scripting Guide: 7.3 Andere Vergleichsoperatoren (scrollen Sie nach unten zur Diskussion von =
und ==
).
true
undfalse
im Zusammenhang mit den meisten Schnipsel unten sind nur einfache Zeichenfolgen, nicht diebash built-ins
!!! Bitte lesen Sie die Antwort von Mike Holt unten. (Dies ist ein Beispiel, wo eine hoch gewählte und akzeptierte Antwort