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)