Powiedzmy, że mam następujący potok:
cmd1 < input.txt |\
cmd2 |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt
Pod pewnymi warunkami chciałbym dodać cmd3
między cmd2
i cmd4
. Czy istnieje sposób, aby utworzyć miły potok warunkowy bez zapisywania wyniku polecenia cmd2 w pliku tymczasowym? Pomyślałbym o czymś takim jak:
cmd1 < input.txt |\
cmd2 |\
(${DEFINED}? cmd3 : cat ) |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt
Odpowiedzi:
Tylko zwykli
&&
i||
operatorzy:(Należy pamiętać, że nie jest wymagany końcowy ukośnik odwrotny, gdy linia kończy się rurą)
Zaktualizuj zgodnie z obserwacją Jonasa .
Jeśli cmd3 może zakończyć się niezerowym kodem wyjścia i nie chcesz
cat
przetwarzać pozostałych danych wejściowych, odwróć logikę:źródło
cat
powróci z niezerowym statusem wyjścia (często występującym podczas uzyskiwania SIGPIPE),cmd3
zostanie uruchomiony. Lepiej użyj jeśli / wtedy / else jak w odpowiedzi Thora lub innych rozwiązaniach, które unikają uruchamianiacat
.if
/else
/fi
działa. Zakładając dowolną powłokę podobną do Bourne'a:źródło
Wszystkie dotychczasowe odpowiedzi zastępują
cmd3
sięcat
. Możesz także uniknąć uruchamiania dowolnego polecenia za pomocą:To POSIX, ale zauważ, że jeśli w
bash
skrypcie, którybash
nie jest w trybiesh
-mode (jak w skrypcie rozpoczynającym się od#! /path/to/bash
), musisz włączyć rozszerzenie aliasu za pomocąshopt -s expand_aliases
(lubset -o posix
).Innym podejściem, które wciąż nie uruchamia niepotrzebnych poleceń, jest użycie polecenia eval:
Lub:
W Linuksie (przynajmniej) zamiast tego
cat
możesz użyć,pv -q
który używasplice()
zamiastread()
+write()
do przesyłania danych między dwoma potokami, co pozwala uniknąć dwukrotnego przenoszenia danych między jądrem a przestrzenią użytkownika.źródło
Jako dodatek do zaakceptowanej odpowiedzi manatwork : bądź świadomy i-fałszywej-lub gotcha i jej interakcji ze strumieniami. Na przykład,
wyjścia
foo
. Nie jest zaskoczeniem,i
oba wyjścia
baz
. (Zauważ, żeecho foo | grep bar
jest to fałsz i nie ma danych wyjściowych). Jednak,nic nie produkuje. To może, ale nie musi być to, czego chcesz.
źródło
else
(A||
) powinien służyć jako działania zerowego utrzymaniu wejście. Więc zastąpieniecat
zeecho
zmiany wszystko co Twój kod znaczenia. Jeśli chodzi o „i-fałszywe-lub gotcha”, nie widzę żadnej ingerencji w rurociąg: pastebin.com/u6Jq0bZe[[ "${DEFINED}" ]] && cmd3 || cat
,cmd3
icat
nie są wzajemnie się wykluczająthen
ielse
oddziałów tej samejif
, ale jeślicmd3
nie, tocat
będą również wykonywane. (Oczywiście, jeślicmd3
zawsze się powiedzie, lub gdy pobiera wszystkie dane wejściowe, więc nie ma nic wstdin
nacat
do procesu, to nie może to kwestia). Jeśli potrzebują zarównothen
ielse
gałęzie, to lepiej użyć wyraźneif
polecenie, a nie&&
a||
.Miałem podobną sytuację, którą rozwiązałem za pomocą funkcji bash :
źródło
Oto alternatywne możliwe rozwiązanie:
konkatenacja nazwanych potoków w celu utworzenia pseudo-potoku:
źródło
Na przyszłość, jeśli przyjeżdżasz tutaj w poszukiwaniu ryb warunkowych , możesz to zrobić w następujący sposób:
źródło