Was ist der Zweck von "&&" in einem Shell-Befehl?

Antworten:

398

&&Mit dieser Option können Sie festlegen, ob der vorherige Befehl erfolgreich ausgeführt wurde. Aus diesem Grund sehen Sie ihn in der Regel als verkettet an do_something && do_something_else_that_depended_on_something.

girasquid
quelle
391

Darüber hinaus haben Sie auch ||das logische oder und ;das ist nur ein Trennzeichen, dem es egal ist, was mit dem Befehl zuvor passiert ist.

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Einige Details dazu finden Sie hier Befehlslisten im Bash-Handbuch.

Plundra
quelle
5
Vielleicht möchten Sie hinzufügen false && echo "Will not be printed".
MTSan
112

Kommandozeile - wozu dient das &&?

In der Schale, wenn Sie sehen

$ command one && command two

Die Absicht ist, den folgenden Befehl auszuführen, &&wenn der erste Befehl erfolgreich ist. Dies ist idiomatisch für Posix-Muscheln und nicht nur in Bash zu finden.

Es soll verhindern, dass der zweite Prozess ausgeführt wird, wenn der erste fehlschlägt.

Sie werden vielleicht bemerken, dass ich das Wort "Absicht" verwendet habe - das hat einen guten Grund. Nicht alle Programme haben das gleiche Verhalten. Damit dies funktioniert, müssen Sie verstehen, was das Programm als "Fehler" betrachtet und wie es damit umgeht, indem Sie die Dokumentation und gegebenenfalls den Quellcode lesen.

Ihre Shell berücksichtigt einen Rückgabewert von 0 für true und andere positive Zahlen für false

Programme geben beim Beenden ein Signal zurück . Sie sollten 0 zurückgeben, wenn sie erfolgreich beendet werden, oder größer als Null, wenn sie dies nicht tun. Dies ermöglicht eine begrenzte Kommunikation zwischen Prozessen.

Das &&wird AND_IFin der Posix-Shell-Grammatik genannt , die Teil einer and_orListe von Befehlen ist, zu denen auch ||die mit einer OR_IFähnlichen Semantik gehört.

Grammatiksymbole, zitiert aus der Dokumentation:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

Und die Grammatik (auch aus der Dokumentation zitiert), die zeigt, dass eine beliebige Anzahl von AND_IFs ( &&) und / oder OR_IFs ( ||) aneinander gereiht werden kann (wie and_orrekursiv definiert):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Beide Operatoren haben die gleiche Priorität und werden von links nach rechts ausgewertet (sie sind linksassoziativ). Wie die Dokumente sagen:

Eine AND-ORListe ist eine Folge von einer oder mehreren Pipelines, die durch die Operatoren "&&"und getrennt sind "||".

Eine Liste ist eine Sequenz von einem oder mehreren UND-ODER - Listen , die von den Operatoren getrennt sind ';'und '&'gegebenenfalls terminiert durch ';', '&'oder.

Die Betreiber "&&"und "||"haben den gleichen Vorrang und werden mit linker Assoziativität bewertet. Beispielsweise schreiben beide folgenden Befehle ausschließlich Balken in die Standardausgabe:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. Im ersten Fall ist false ein Befehl, der mit dem Status von beendet wird 1

    $ false
    $ echo $?
    1

    was bedeutet, echo fooläuft nicht (dh Kurzschluss echo foo). Dann wird der Befehl echo barausgeführt.

  2. Im zweiten Fall wird true mit einem Code von beendet 0

    $ true
    $ echo $?
    0

    und wird daher echo foonicht ausgeführt, dann echo barwird ausgeführt.

Aaron Hall
quelle
31

Eine häufig verwendete Verwendung für '&&' ist das Kompilieren von Software mit Autotools. Zum Beispiel:

./configure --prefix=/usr && make && sudo make install

Wenn die Konfiguration erfolgreich ist, wird make ausgeführt, um zu kompilieren. Wenn dies erfolgreich ist, wird make als root ausgeführt, um das Programm zu installieren. Ich benutze dies, wenn ich größtenteils sicher bin, dass die Dinge funktionieren werden, und es mir ermöglicht, andere wichtige Dinge zu tun, wie den Stapelüberlauf zu betrachten und den Fortschritt nicht zu überwachen.

Manchmal werde ich wirklich mitgerissen ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Ich mache das, wenn ich zum Beispiel ein Linux von Grund auf neu mache.

Nigel Atkinson
quelle
2
Gut in REPL, aber für Skripte würde ich set -o errexitBash bevorzugen .
Franklin Yu
19

&&Zeichenfolgen Befehle zusammen. Aufeinanderfolgende Befehle werden nur ausgeführt, wenn vorhergehende erfolgreich sind.

In ähnlicher Weise kann ||der nachfolgende Befehl ausgeführt werden, wenn der vorhergehende fehlschlägt.

Siehe Bash Shell-Programmierung .

Dean Burge
quelle
8

Siehe das Beispiel:

mkdir test && echo "Something" > test/file

Shell versucht, ein Verzeichnis zu erstellen, testund versucht dann nur dann , eine Datei darin zu erstellen , wenn dies erfolgreich war .

Sie können also eine Folge von Schritten unterbrechen, wenn einer von ihnen fehlgeschlagen ist.

alno
quelle
8

Es ist eine zweite Anweisung auszuführen, wenn die erste Anweisung erfolgreich endet. Wie eine if-Anweisung:

 if (1 == 1 && 2 == 2)
  echo "test;"

Seine ersten Versuche, wenn 1 == 1, wenn das wahr ist, prüft es, ob 2 == 2

Nick
quelle
1
Könnte jemand erklären, warum dies für Benutzer, die über die Frage stolpern, abgelehnt wurde?
user3243242
1
@ user3243242 es ist nicht falsch, nur ein schlechtes Beispiel, um die Verwendung von&&
dan
Es ist ein großartiger Einblick, wie ifTests in Bash funktionieren. Ich habe es nie als eine Kette von Vergleichsbefehlen angesehen, die kaputt gingen, wenn einer von ihnen fehlschlug. Also hast du meine Gegenstimme :)
PiRK
1
Die Konsequenz ist, dass Sie das gegenteilige Verhalten ||eei || leu || uie || echo prout3 || echo "never executed"
erzielen
7

command_1 && command_2: Befehl_2 nur ausführen, wenn Befehl_1 erfolgreich ausgeführt wird.

command_1 || command_2: Befehl_2 nur ausführen, wenn Befehl_1 nicht erfolgreich ausgeführt wird.

Es fühlt sich ähnlich an, wie eine 'if'-Bedingung in einer gängigen Programmiersprache ausgeführt wird, wie z. B. in if (condition_1 && condition_2){...}Bedingung_2, wenn Bedingung_1 ist, falseund in if (condition_1 || condition_2){...}Bedingung_2 wird weggelassen, wenn Bedingung_1 ist true. Sehen Sie, es ist der gleiche Trick, den Sie zum Codieren verwenden :)

Xiaonin Li
quelle
Ich weiß nicht, was du mit 'genau das Gegenteil' meinst, aber $ echo '1' || Echo '2' gibt nur '1' aus. und $ false_command || Echo '2' gibt eine Fehlermeldung und '2' in der nächsten Zeile aus. Könnten Sie etwas mehr darüber erklären, was Ihrer Meinung nach daran falsch ist?
Xiaonin Li
ho dude, ich war gestern bestimmt zu müde. Entschuldigung dafür, es war nur ich: / Ich brauche dich, um etwas in deiner Antwort zu bearbeiten, wenn du willst, dass ich abstimme (um deine Antwort auf 0 zu bringen, bitte jetzt Stapelüberlauf um Bearbeitung, damit ich nicht kann)
Arount
@Arount, es ist in Ordnung, mach dir keine Sorgen. Also habe ich gerade eine Bearbeitung eingereicht. Können Sie die Abwärtsabstimmung jetzt entfernen?
Xiaonin Li
yep, wieder, sorry, wirklich
Arount
0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

Wenn das Programm den Befehl if prüft, erstellt das Programm eine Zahl namens Exit-Code. Wenn beide Bedingungen erfüllt sind, ist der Exit-Code Null (0), andernfalls ist der Exit-Code eine positive Zahl. Nur wenn Gleich angezeigt wird, wenn der Exit-Code Null (0) ist, bedeutet dies, dass beide Bedingungen erfüllt sind.

Amin
quelle
Willkommen beim Stackoverflow. Bitte stellen Sie sicher, dass Ihr Code-Snippet funktioniert, bevor Sie hier posten. Sie müssen es korrigierenif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu
1
Vielen Dank an @ZhengQu für Ihren Befehl. Es wurde getan.
Amin