Gibt es eine Möglichkeit, die Befehlsstruktur neu zu schreiben, A && B || C | D
sodass 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 | D
sodass 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 || C
wird in geleitet werden D
.
sh
:)
A
sich 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 B
oder laufen C
, aber A && B || C
das schaffst du nicht. Wenn dies A
gelingt, aber ausgeführt wird B
und fehlschlägt, wird es ausgeführt C
.
Hinweis 1: Wenn Sie irgendwie garantieren können, dass das B
immer 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 A
aus, 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 bash
und pgrep bash | cat
und if true; then pgrep bash; fi
und { pgrep bash; }
haben eine Ausgabezeile; ( pgrep bash; )
und ( pgrep bash; ) | cat
und { pgrep bash; } | cat
und if true; then pgrep bash; fi | cat
haben 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 A
als Eingang D
. Um dies zu erreichen, müssen Sie A
je nach Bedarf eine Stream-Umleitung aktivieren.
Wenn Sie die Ausgabe A
trotzdem verwerfen möchten :
{ A >/dev/null && B || C; } | D
Wenn Sie die Ausgabe von A
auf dem Terminal sehen möchten :
{ A >/dev/tty && B || C; } | D
Wenn Sie die Ausgabe von A
als Eingabe eines nachfolgenden Befehls E
benötigen, benötigen Sie eine zusätzliche Befehlsgruppe und eine Stream-Umleitung:
{ { A >&3 && B || C; } | D; } 3>&1 | E
Wenn Ihnen das alles zu dunkel erscheint (wie mir), empfehle ich Ihnen, die spezielle Shell-Variable für den Exit-Status von zu verwenden A
und 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.)
A
aus der Pipeline herausgezogen bin .
A && (B || C) | D
wenn Sie nicht möchten, dass B, C oder D ausgeführt werden, wenn A ausfällt