Gibt es eine Möglichkeit, die Befehlsstruktur neu zu schreiben, A && B || C | Dsodass entweder B oder C in D weitergeleitet werden?
Mit dem aktuellen Befehl werden entweder nur B oder sowohl C als auch D ausgeführt.
Beispielsweise:
Gibt es eine Möglichkeit, die Befehlsstruktur neu zu schreiben, A && B || C | Dsodass entweder B oder C in D weitergeleitet werden?
Mit dem aktuellen Befehl werden entweder nur B oder sowohl C als auch D ausgeführt.
Beispielsweise:
Antworten:
Ja, in bash können Sie Klammern verwenden:
(A && B || C) | D
Auf diese Weise der Ausgang A && B || Cwird in geleitet werden D.
sh:)
Asich in der Unterschale befindet, schließt dies auch ein A.)
Sie können dies als schreiben
if A; then B; else C; fi | D
Du sagst, du willst entweder Boder laufen C, aber A && B || Cdas schaffst du nicht. Wenn dies Agelingt, aber ausgeführt wird Bund fehlschlägt, wird es ausgeführt C.
Hinweis 1: Wenn Sie irgendwie garantieren können, dass das Bimmer gelingt und Sie bei einer kurzen Version bleiben möchten, dann würde ich mich trotzdem dafür entscheiden
{ A && B || C; } | D
über ( ... ), da letztere unnötigerweise die Erzeugung einer neuen Unterschale erzwingt, die möglicherweise wegoptimiert wird oder nicht.
Anmerkung 2: Beide Formen gehen davon Aaus, dass keine Ausgabe erfolgt, was in Ihrem Beispiel zutrifft, aber nicht unbedingt im Allgemeinen. Das kann vermieden werden durch
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }aufgrund der Pipe keine Unterschale erstellt werden muss? Ich beobachte folgendes Verhalten: pgrep bashund pgrep bash | catund if true; then pgrep bash; fiund { pgrep bash; }haben eine Ausgabezeile; ( pgrep bash; )und ( pgrep bash; ) | catund { pgrep bash; } | catund if true; then pgrep bash; fi | cathaben zwei Ausgabezeilen.
... | ...bewirkt, dass eine Subshell erstellt wird, was unvermeidlich ist. ( ... )Zumindest theoretisch wird eine zusätzliche Subshell erstellt, die dies { ...; }vermeidet, aber das habe ich mit "kann oder kann nicht optimiert werden" gemeint: Es ist möglich, dass in diesem speziellen Fall die Shell merkt, dass es keine Rolle spielt, die Wirkung wäre das gleiche.
Die accepter Antwort ist richtig , aber es ist nicht die mögliche Verwendung Fall Deckung nicht die Ausgabe haben Aals Eingang D. Um dies zu erreichen, müssen Sie Aje nach Bedarf eine Stream-Umleitung aktivieren.
Wenn Sie die Ausgabe Atrotzdem verwerfen möchten :
{ A >/dev/null && B || C; } | DWenn Sie die Ausgabe von Aauf dem Terminal sehen möchten :
{ A >/dev/tty && B || C; } | DWenn Sie die Ausgabe von Aals Eingabe eines nachfolgenden Befehls Ebenötigen, benötigen Sie eine zusätzliche Befehlsgruppe und eine Stream-Umleitung:
{ { A >&3 && B || C; } | D; } 3>&1 | EWenn Ihnen das alles zu dunkel erscheint (wie mir), empfehle ich Ihnen, die spezielle Shell-Variable für den Exit-Status von zu verwenden Aund damit zu arbeiten:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Wenn Sie prägnanter, aber nicht zu geheimnisvoll sein möchten, empfehle ich Folgendes:
A; { [ $? -eq 0 ] && B || C; } | D
(Siehe auch den letzten Teil der Antwort von hvd, den ich nicht bemerkt habe, als ich meine ursprüngliche Antwort geschrieben habe.)
Aaus der Pipeline herausgezogen bin .
A && (B || C) | Dwenn Sie nicht möchten, dass B, C oder D ausgeführt werden, wenn A ausfällt