Isso
make 2>&1 | tee myfifo | grep -E "errors|warnings" myfifo > errors.log | cat myfifo
P1 P2 P3
O comando faz pouco sentido. Ele inicia esses 4 comandos simultaneamente com os tubos entre eles:
-
make 2>&1: stdout e stderr vai para P1 -
tee myfifo: stdin de P1, stdout para P2. Portanto,teegrava a saída emmyfifoe P2. -
grep -E "errors|warnings" myfifo > errors.log: stdin de P2, mas você está passando um nome de arquivo (myfifo) paragrep, entãogrepnão lerá de seu stdin. stdout vai paraerrors.log, nada grava em P3 -
cat myfifo: stdin do P3, mas comocatrecebe um nome de arquivo, ele o lê. Portanto,grepecatleemmyfifoao mesmo tempo.
Como nada lê de P2, tee irá travar quando P2 estiver cheio. Além disso, cat não exibirá as partes de myfifo que foram lidas por grep .
make 2>&1 | tee myfifo | grep -e errors -e warnings > errors.log | cat myfifo
está mais perto do que você quis dizer. Novamente, o P3 não é usado, mas estamos usando o | para iniciar o cat ao mesmo tempo e esperar por ele.
Ou você poderia fazer:
make 2>&1 | tee myfifo & grep -e errors -e warnings > errors.log
wait
Se você precisar de mais grep s, precisará de mais fifos:
make 2>&1 | tee fifo2grep1 fifo2grep2 &
grep errors fifo2grep1 > errors.log &
grep warnings fifo2grep2 > warnings.log
wait
Em sistemas que suportam /dev/fd/x , você também pode fazer:
make 2>&1 | { tee /dev/fd/3 | grep -e errors -e warnings 3>&-; } 3>&1
(normalmente, isso é o que a substituição do processo faz nos shells que a suportam).
Com 2 grep s, isso se torna:
make 2>&1 |
{
{
tee /dev/fd/3 /dev/fd/4 |
grep errors > errors.log 3>&- 4>&-
} 4>&1 |
grep warnings > warnings.log 3>&-
} 3>&1