Em
yes "test" | while read line; do echo $line; done | grep -E "*" | grep -m3 "test"existem quatro processos, executando
yes , o programa shell executando esse while loop, grep e grep , respectivamente. O último processo no pipeline termina, fechando o final de leitura do seu canal de entrada, após três correspondências. O pipeline termina então por uma cadeia de SIGPIPE s da maneira usual para pipelines prematuramente terminados, já que cada estágio da pipline acaba gravando em um cano quebrado.
Em
yes "test" | while read line; do echo $line | grep -E "*"; done | grep -m3 "test"existem três processos executando
yes , o programa shell e grep , respectivamente. Mas o segundo processo, aquele que executa o programa shell, está gerando continuamente dois outros processos filhos, um executando echo e outro executando grep instance. É esse último processo que recebe o SIGPIPE e não o processo executando o programa shell. É esse último processo que, afinal, está realmente escrevendo para o cano quebrado.
A conseqüência disso é que o segundo estágio do pipeline, o shell que executa o while loop, nunca é ele terminado com SIGPIPE e apenas continua em execução, gerando um pipeline filho ; de novo e de novo. Ele vê o pipeline filho que gerou terminar com um SIGPIPE , é claro, mas para o shell que está executando o loop while que é não um motivo para encerrar o loop.