Ooh, uma condição de corrida! Há algumas coisas acontecendo aqui nos bastidores para produzir esse efeito.
Primeiro, se um processo tentar gravar em um pipe cuja outra extremidade tenha sido fechada, esse processo receberá um sinal SIGPIPE
. Por padrão, isso encerra o processo. Por que você quer isso? Se você executar cat my_huge_file | head -3
, verá apenas as três primeiras linhas do arquivo e, por causa do mecanismo de sinalização, cat
sabe parar após essas três linhas. Sem ele, ele leria o arquivo inteiro.
Em segundo lugar, todos os processos em um pipeline executados em paralelo e qual processo será concluído primeiro é imprevisível. Quando um processo termina, todos os seus descritores de arquivo são fechados - incluindo as extremidades de leitura de qualquer canal.
Então, o que está acontecendo é que às vezes, por exemplo, file3
termina completamente antes que file2
tenha escrito em sua stdout. Então, quando file2
tentar escrever, ele recebe SIGPIPE
e sai sem atingir a linha echo stderr2
. Porém, outras vezes, file2
consegue gravar no stdout antes de file3
ser concluído e, nesse caso, ele continua.