it-swarm.com.de

Gibt es einen Unterschied zwischen '&&' und ';' Symbole in einem Standard-BASH-Terminal?

Beide scheinen BASH zu signalisieren, mit einem anderen Befehl zu beginnen, der den Symbolen folgt. Gibt es jedoch einen deutlichen Unterschied?

55
user6658

Mit dieser Zeile:

command1 && command2

befehl2 wird ausgeführt, wenn (und nur wenn) Befehl1 den Beendigungsstatus Null zurückgibt, während 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.

73
user8290

Sie können den Unterschied selbst ausprobieren:

  1. ls /invalid/path && echo "hello!"
    Da/invalid/path nicht existiert, kann ich Ihnen 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!") Ist nie ausgeführt, weil die erste Hälfte fehlgeschlagen ist.

  2. ls /invalid/path ; echo "hello!"
    Dieselbe Fehlermeldung wie zuvor, aber diesmal wird der zweiter Teil ausgeführt!
    ls:/invalid/path: Keine solche Datei oder kein solches Verzeichnis
    Hallo!

Warum ist das nützlich?
Angenommen, Sie möchten eine Datei mit dem Namen archive.tar.gz extrahieren
Sie können den Befehl tar zxvf archive.tar.gz && rm archive.tar.gz verwenden.
Sollte das Extrahieren des Archivs aus irgendeinem Grund fehlschlagen, 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.

41

&& ist AND, was bedeutet, dass der zweite Befehl nur ausgeführt wird, wenn der erste true zurückgibt (keine Fehler).

8
Ward Muylaert

pdate: Ich habe einige der möglichen Fallen als Skript hinzugefügt:

Weil sonst niemand "||" erwähnt hat, werde ich

pdate2: hier einige wichtige Umformulierungen
&& ist 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 des bisherige zuletzt ausgeführt Anweisung und übergibt die Kontrolle an die Anweisung oder Sub-Shell unmittelbar nach dem && ... sie übergibt die Kontrolle nur, wenn $? ist wahr.

|| ist ähnlich und wird häufig nach einer &&-Anweisung angezeigt, prüft jedoch auf einen false Rückgabewert ($?) aus dem bisherige zuletzt ausgeführt 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
is not verhält sich nicht wie ein C/C++ - Ternär. 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, die Sie erwarten.

[[Bedingung]] && echo Hallo || Echo Auf Wiedersehen .... ist in der Regel sicher,
weil ein wohlgeformtes Echo wahr ist.
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 

7
Peter.O

versuchen

falsch && echo "hallo"

und

falsch; Echo "Hallo"

sieh den Unterschied

1
Petrie Wong

Der Befehl (Funktion im Falle eines Skripts) nach && 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.

0
theTuxRacer