Angenommen, ich habe die folgende Pipeline:
cmd1 < input.txt |\
cmd2 |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt
Unter bestimmten Voraussetzungen möchte ich ein cmd3
zwischen cmd2
und hinzufügen cmd4
. Gibt es eine Möglichkeit, eine bedingte Pipeline zu erstellen, ohne das Ergebnis von cmd2 in einer temporären Datei zu speichern? Ich würde an etwas denken wie:
cmd1 < input.txt |\
cmd2 |\
(${DEFINED}? cmd3 : cat ) |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt
Antworten:
Nur das Übliche
&&
und||
Operatoren:(Beachten Sie, dass kein abschließender Backslash erforderlich ist, wenn die Linie mit einer Pipe endet.)
Update nach Jonas 'Beobachtung .
Wenn cmd3 möglicherweise mit einem Exit-Code ungleich Null endet und Sie
cat
die verbleibende Eingabe nicht verarbeiten möchten , kehren Sie die Logik um:quelle
cat
mit einem Exit-Status ungleich Null zurückgegeben wird (häufig beim Abrufen eines SIGPIPE),cmd3
wird ausgeführt. Verwenden Sie besser if / then / else wie in Thors Antwort oder andere Lösungen, die nicht ausgeführt werden könnencat
.if
/else
/fi
funktioniert. Angenommen, eine Bourne-ähnliche Shell:quelle
Alle bisher gegebenen Antworten ersetzen
cmd3
mitcat
. Sie können auch die Ausführung von Befehlen vermeiden, wenn Sie:Das ist POSIX, aber beachten Sie, dass Sie in einem
bash
Skript, in dembash
sich keinsh
-mode befindet (wie bei einem Skript, das mit beginnt#! /path/to/bash
), die Alias-Erweiterung mitshopt -s expand_aliases
(oderset -o posix
) aktivieren müssen .Ein anderer Ansatz, bei dem immer noch keine unnötigen Befehle ausgeführt werden, ist die Verwendung von eval:
Oder:
Unter Linux (zumindest), statt
cat
, könnten Sie verwenden ,pv -q
welche verwendensplice()
anstelle vonread()
+write()
die Daten über zwischen den beiden Rohren zu passieren , die zweimal zwischen Kernel- und User - Space der Daten bewegt vermeiden.quelle
Als Ergänzung zur akzeptierten Antwort von manatwork : Achten Sie auf das And -False-or-Gotcha und dessen Interaktion mit Streams. Zum Beispiel,
Ausgänge
foo
. Nicht überraschend,und
beide ausgang
baz
. (Beachten Sie, dassecho foo | grep bar
falsch ist und keine Ausgabe hat). Jedoch,gibt nichts aus. Dies kann oder kann nicht das sein, was Sie wollen.
quelle
else
(oder||
) sollte als Nulloperation fungieren und die Eingabe unverändert lassen. Ersetzen Sie alsocat
durchecho
Änderungen alles, was Ihren Code irrelevant macht. Die in Bezug auf „und-Falsch oder Gotcha“, sehe ich keine Interferenz mit der Pipeline: pastebin.com/u6Jq0bZe[[ "${DEFINED}" ]] && cmd3 || cat
,cmd3
undcat
sind nicht gegenseitig austhen
undelse
Zweige derselbenif
, aber wenncmd3
nicht, danncat
wird auch ausgeführt werden. (Natürlich, wenncmd3
gelingt es immer wieder , oder wenn sie alle die Eingabe verbraucht , so gibt es nichts mehr übrig instdin
fürcat
zu verarbeiten, dann die es keine Rolle kann.) Wenn Sie beide brauchenthen
undelse
Zweige, es besser ist , einen expliziten zu verwendenif
Befehl nicht&&
und||
.Ich hatte eine ähnliche Situation, die ich mit Bash- Funktionen gelöst habe :
quelle
Hier ist eine alternative mögliche Lösung:
Verketten von Named Pipes, um eine Pseudo-Pipeline zu erstellen:
quelle
Wenn Sie hierher kommen, um nach bedingten Pfeifen in Fischen zu suchen , gehen Sie wie folgt vor:
quelle