Beide scheinen BASH zu signalisieren, mit einem anderen Befehl zu beginnen, der den Symbolen folgt. Gibt es jedoch einen deutlichen Unterschied?
Beide scheinen BASH zu signalisieren, mit einem anderen Befehl zu beginnen, der den Symbolen folgt. Gibt es jedoch einen deutlichen Unterschied?
Antworten:
Mit dieser Zeile:
command1 && command2
Befehl2 wird ausgeführt, wenn (und nur wenn) Befehl1 den Exit-Status Null zurückgibt, wobei in dieser Zeile:
command1 ; command2
Befehl1 und Befehl2 werden unabhängig voneinander ausgeführt. Mit dem Semikolon können Sie viele Befehle in einer Zeile eingeben.
Sie können den Unterschied selbst ausprobieren:
ls /invalid/path && echo "hello!"
Da / invalid / path nicht existiert, kann ls die Verzeichnisliste nicht anzeigen. Es wird mit einer Fehlermeldung fehlschlagen: "ls: / invalid / path: Keine solche Datei oder Verzeichnis".
Die zweite Hälfte des Befehls (Echo "Hallo!") Wird nie ausgeführt, da die erste Hälfte fehlgeschlagen ist.
ls /invalid/path ; echo "hello!"
Es erscheint die gleiche Fehlermeldung wie zuvor, diesmal wird jedoch der zweite Teil ausgeführt !
ls: / invalid / path: Keine solche Datei oder Verzeichnis
hallo!
Warum ist das nützlich?
Angenommen, Sie möchten eine Datei mit dem Namen archive.tar.gz extrahieren.
Sie könnten den Befehl verwenden tar zxvf archive.tar.gz && rm archive.tar.gz
.
Wenn das Extrahieren des Archivs aus irgendeinem Grund fehlschlägt, wird der zweite Teil nicht ausgeführt! Sie können es erneut versuchen.
Wenn du benutzt ; In der gleichen Situation wird das Archiv gelöscht und Sie können es nicht erneut versuchen.
&&
ist AND
, was bedeutet, dass der zweite Befehl nur ausgeführt wird, wenn der erste true zurückgegeben hat (keine Fehler).
AND
Ausführung der 2. Parameter irrelevant wird, wenn der erste gleich ist, false
und so der zugrunde liegende Code optimiert wird, um die Bewertung des 2. Parameters zu verschieben, bis er weiß, was der erste ist.
&&
ist nur ein binärer Operator, eine Funktion. Das einzige "Besondere" ist, dass es sich um die Infixnotation (die ohnehin für die meisten dieser Operatortypen Standard ist) und die verzögerte Ausführung des zweiten Operanden handelt. Die verzögerte Ausführung gibt ihm in der Tat die Fähigkeit , als etwas zu verwenden , die vom Konzept her als betrachtet werden können if
Aussage in diesem Zusammenhang , aber das dauert nicht weg von der Tatsache , dass es ursprünglich Nutzung bestimmt ist , ist innerhalb der bedingten einer tatsächlichen if
Anweisung. Die Verwendung hier ist wirklich eher ein "Hack".
a && b || c = (a && b) || c
. Einfache Reihenfolge der Auswertung. Da gibt es wirklich kein Geheimnis. Wenn Sie sie wie Ihre typischen Funktionen schreiben würden, würde es einfach so aussehen or(and(a, b), c)
. Diese Logik ist die gleiche innerhalb einer if
bedingten sowie , wenn es direkt in die Befehlszeile eingeben , da &&
und ||
sind Operatoren , sie umfassen zwei Operanden und sie kehren anderen.
Update : Ich habe einige der möglichen Fallen als Skript hinzugefügt:
Weil sonst niemand "||" erwähnt hat, werde ich
Update2 : Einige wichtige Umformulierungen hier
&& sind wie ein "dann" einer "wenn" -Anweisung, die auf "wahr" reagiert.
|| ist NICHT wie das "else" einer "if" -Anweisung ..
|| ist wie ein "dann" einer "wenn" -Anweisung, die auf "falsch" reagiert
Genauer gesagt, testet && das $? Rückgabewert der vorherigen zuletzt ausgeführten Anweisung und übergibt die Steuerung an der Anweisung oder Unterschale unmittelbar nach dem && ... es geht nur die Kontrolle , wenn $? ist wahr.
|| ähnlich ist, und wird häufig nach einer && Anweisung gesehen, aber es testet für einen falschen Rückgabewert ($?) von der vorherigen zuletzt ausgeführten Anweisung ... NB! , Nota Bene! Gut zu beachten! .... wenn die vorhergehende Anweisung eine &&-Anweisung ist, die false wiederholt, wenn Sie erwarten, dass es true ist, dann || wird auf false reagieren, daher kann es riskant sein, beide in derselben Zeile zu mischen
Der Hauptgrund, den ich zu machen versuche, ist in Bezug auf einen Fehler, den ich gemacht habe. dh:
## [[Bedingung]] && A || B
ist nicht benimmt sich nicht wie ein C / C ++ Stil ternäre. dh:
// (Bedingung)? A: B
Im folgenden Skript finden Sie Beispiele für "unerwartete" Ergebnisse von "A".
Der Basistest und das && und das || Anweisung muss alle in der gleichen Zeile sein ...
Führen Sie dieses Skript aus, um festzustellen, wo bei Verwendung von && und || Probleme auftreten können
Die zuletzt ausgeführte Anweisung ist möglicherweise nicht die erwartete.
[[Bedingung]] && echo Hallo || echo Goodbye .... ist normalerweise sicher,
da ein gut geformtes Echo true zurückgibt.
aber was ist mit dem Zugriff auf eine Datei, die nicht existiert?
#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo ======
((1==1)) && echo " ((1==1)) rc=$? ..&&.. condition is true" || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && echo " \$0 0 rc=$? ..&&.. condition is true" || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. condition is true" || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && echo " \$0 1 rc=$? ..&&.. condition is true" || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo ======
((1==1)) || echo " ((1==1)) rc=$? ..||.. condition is true" && echo " ((1==1)) rc=$? ..&&.. condition is false"
$0 0 || echo " \$0 0 rc=$? ..||.. condition is true" && echo " \$0 0 rc=$? ..&&.. condition is false"
((1!=1)) || echo " ((1!=1)) rc=$? ..||.. condition is true" && echo " ((1!=1)) rc=$? ..&&.. condition is false"
$0 1 || echo " \$0 1 rc=$? ..||.. condition is true" && echo " \$0 1 rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
exit
Versuchen
falsch && echo "hallo"
und
falsch; Echo "Hallo"
sieh den Unterschied
Der Befehl (Funktion im Falle eines Skripts) danach &&
wird abhängig vom RETVAL des ersten Befehls (Funktion im Falle eines Skripts) ausgeführt. Erzwingt bei Erfolg, dass der erste Befehl den Wert 0 zurückgibt. Wir können den Rückgabewert überprüfen, um weitere Befehle auszuführen.