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/truemit irgendeiner anderen Variante des trueBefehls. In diesem Fall truehandelt es sich truelediglich 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_flatauf die Zeichenfolge "true".
- Versuchen Sie, die Zeichenfolge
"true"als Befehl zu analysieren .
- Suchen Sie den
trueBefehl und führen Sie ihn aus (entweder integriert oder /bin/trueabhängig von der Bash-Version).
- Vergleichen Sie den Exit-Code des
trueBefehls (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
ifAnweisung austhen
Klammern:
- Erweitern Sie die Variable
$the_world_is_flatauf 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
ifAnweisung aus then.
Der Code ohne Klammern funktioniert, da der trueBefehl einen Exit-Code von 0 zurückgibt, der den Erfolg anzeigt. Der Code in Klammern funktioniert, da der Wert von $the_world_is_flatmit dem Zeichenfolgenliteral trueauf 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 varwird 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 ==).
trueundfalseim 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