enquanto ler, grep, pipes e pendurar

2
yes "test" | grep -m3 "test"

imprime

test
test
test

e depois termina. Então faz

yes "test" | while read line; do echo $line; done | grep -m3 "test"

e

yes "test" | while read line; do echo $line; done | grep -E "*" | grep -m3 "test"

Mas

yes "test" | while read line; do echo $line | grep -E "*"; done | grep -m3 "test"

imprime

test
test
test

e depois trava. O que está acontecendo aqui?

    
por Robby McKilliam 21.11.2017 / 03:00

1 resposta

6

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.

    
por 21.11.2017 / 03:31

Tags