Gibt es einen Unterschied zwischen `;` und `&&` und `|`?

Gibt es einen Unterschied zwischen `;` und `&&` und `|`?

Wenn Sie mehrere Befehle ausführen möchten, können Sie verwenden ;, &&und|

So: killall Finder; killall SystemUIServer, cd ~/Desktop/ && rm CachesOder: man grep | man catzum Beispiel.

Aber gibt es einen Unterschied zwischen |und ;? &&Wenn ja, was ist der Unterschied?

Antwort1

  • ;: Durch ein getrennte Befehle ; werden nacheinander ausgeführt. Die Shell wartet, bis jeder Befehl nacheinander beendet ist.

  • &&: Der nachfolgende Befehl &&wird genau dann ausgeführt, wenn der vorherige Befehl &&den Beendigungsstatus Null zurückgibt. Sie können es sich als ANDOperator vorstellen.

  • |: eine Pipe. Im Ausdruck command1 | command2Die Standardausgabe von command1 ist über eine Pipe mit der Standardeingabe von command2 verbunden.

Es gibt noch weitere ähnliche Steueroperatoren, die der Erwähnung wert sind:

  • ||: Der Befehl danach ||wird genau dann ausgeführt, wenn der Befehl davor ||einen Exit-Status ungleich Null zurückgibt. Sie können es sich als OROperator vorstellen. Bitte beachten Sie, dass |und ||zwei völlig verschiedene Dinge sind.

  • &: Die Shell führt den durch beendeten Befehl &im Hintergrund aus, wartet nicht, bis der Befehl beendet ist, und gibt sofort den Exitcode 0 zurück. Hat wiederum &nichts mit zu tun &&.

  • |&: eine Abkürzung dafür 2>&1 |, dass sowohl die Standardausgabe als auch der Standardfehler von Befehl1 über die Pipe mit der Standardeingabe von Befehl2 verbunden sind.

Wenn Sie dann verwenden, zshkönnen Sie den Befehl zusätzlich auch mit &|oder starten &!. In diesem Fall wird der Job sofort abgelehnt und hat nach dem Start keinen Platz mehr in der Jobtabelle.

Antwort2

Betrachten Sie zwei Befehle Aund B. Wenn Sie schreiben

A | B

Aund Bwerden parallel ausgeführt, und die Standardausgabe von Awird als Standardeingabe von gesendet B.

Wenn Sie schreiben

A; B

Aausgeführt wird, dann Bwird ausgeführt (es sei denn, set -ees wurde verwendet und Aendet mit einem Exit-Status ungleich Null; in diesem Fall wird die Shell direkt danach beendet A).

Wenn Sie schreiben

A && B

Aausgeführt wird, Bwird dann nur ausgeführt, wenn Aerfolgreich beendet wurde (Null-Exit-Status). Diese Form kann sicherer sein als die vorherige, z. B. mit

cd some_dir && rm file*

Dadurch &&wird sichergestellt, dass die richtigen Dateien entfernt werden, d. h. Dateien werden nur entfernt, wenn dies cderfolgreich war.

Antwort3

In den anderen Antworten werden , und bereits erläutert |, &&daher ;füge ich noch etwas hinzu, wonach Sie nicht ausdrücklich gefragt haben: ||.

A || B

Awird ausgeführt und dann Bnur, wenn Aein Fehler auftritt. Dies ist nützlich, um auf Fehlerbedingungen zu reagieren:

martin@martin ~ % rm doesnotexist 2>/dev/null || echo "failed to delete file"
failed to delete file

(Dies 2>/dev/nullist notwendig, um die Fehlermeldung rmselbst zu verbergen.)

Antwort4

Niemand scheint zu erklären, warum Sie angesichts Ihrer tatsächlichen Beispiele jedes davon verwenden würden. Ich werde es versuchen:

killall Finder; killall SystemUIServer

Die Ausführung eines Befehls wie killallkann einige Zeit in Anspruch nehmen. Durch die Verwendung des Semikolons können Sie beide Befehle gleichzeitig eingeben und dann während der Wartezeit etwas anderes tun. Auf diese Weise müssen Sie nicht zweimal warten (einmal für jeden Befehl).

cd ~/Desktop/ && rm Caches

Sie möchten das Verzeichnis entfernen ~/Desktop/Cachesund im Verzeichnis landen ~/Desktop. Was Sie nicht tun möchten, ist, das Verzeichnis Caches aus dem aktuellen Verzeichnis zu entfernen (bevor Sie es ändern). Daher überprüfen Sie, &&ob der Verzeichniswechsel erfolgreich war, bevor Sie Ihren Befehl zum Entfernen ausführen.

man grep | man cat

Das ergibt für mich keinen Sinn. Der manBefehl verarbeitet keine Eingaben, daher bringt es nichts, Dinge dorthin weiterzuleiten. Vielleicht meinten Sie

man grep || man cat

Das würde versuchen, die Manpage für zu finden grepund wenn dies nicht möglich ist, würde die Manpage für angezeigt cat. Oder vielleicht meinten Sie

man grep | cat

Dadurch catwird die Manpage angezeigt, statt des Pagers (normalerweise less). |Die Ausgabe wird manan den Befehl umgeleitet cat(der einfach alles auf den Bildschirm ausgibt). Dies kann in einer GUI nützlich sein, in der Sie mit der Bildlaufleiste in der Datei vor- und zurückblättern können, anstatt die Tastaturbefehle in Less zu verwenden.

Hinweis: Wenn Sie wissen möchten, was ; && | ||in allgemeineren Fällen zu tun ist, würde ich vorschlagen, sich die Antwort von jimmij anzusehen. Ich versuche nur zu erklären, was in den Beispielen aus der Frage passiert.

verwandte Informationen