São as mesmas coisas que em:
- Como sair cedo do tubo perto?
- Grep demora a sair depois de encontrar correspondência?
- limite para encontrar a saída E evitar o sinal 13
Em:
cmd1 | cmd2
Seu shell acaba aguardando até que cmd1 termine mesmo depois de cmd2 ter terminado. Esse não é o caso de todas as conchas. Alguns como o shell Bourne ou Korn não fazem por exemplo.
Quando cmd2 morre, o canal no stdout de cmd1 se torna quebrado , mas isso não termina cmd1 instantaneamente.
cmd1 terminará na próxima vez que tentar gravar nesse pipe. Em seguida, ele receberá um SIGPIPE cuja ação padrão é encerrar o processo.
Com cmd1 == tail -f file e cmd2 == sed /w/q , tail -f lerá as últimas 10 linhas do arquivo e as gravará no stdout (o canal), normalmente em um bloco, a menos que o as linhas são realmente grandes e ficam ali esperando que mais texto seja anexado a file .
sed , que é executado simultaneamente, aguardará entrada em seu stdin, lerá, processará linha por linha e será encerrado se houver uma linha que contenha w .
Tão logo (ou possivelmente com um atraso de uma linha com alguma sed de implementação) quando encontra essa linha, ela sai, mas, nesse momento, tail já escreveu para o pipe tudo o que tinha para ESCREVER, então ele não receberá um SIGPIPE, a menos que algum texto adicional seja adicionado posteriormente ao arquivo (ponto no qual ele fará a% fatalwrite()).
Se você quiser que cmd1 termine assim que cmd2 termine, você precisará de algo para desativá-lo quando cmd2 terminar. Como com:
sh -c 'echo "$$"; exec tail -f test.txt' | {
IFS= read pid
sed /w/q
kill -s PIPE "$pid"
}
Ou com bash :
{ sed /w/q; kill -s PIPE "$!"; } < <(exec tail -f text.txt)