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,tee
grava a saída emmyfifo
e P2. -
grep -E "errors|warnings" myfifo > errors.log
: stdin de P2, mas você está passando um nome de arquivo (myfifo
) paragrep
, entãogrep
não lerá de seu stdin. stdout vai paraerrors.log
, nada grava em P3 -
cat myfifo
: stdin do P3, mas comocat
recebe um nome de arquivo, ele o lê. Portanto,grep
ecat
leemmyfifo
ao 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