Testei o seguinte com bash e dash, e parece que trava de forma confiável:
[ -p pipe ] || mkfifo pipe
i=0
while [ $i -lt 10 ]; do
<pipe cat &
: $(( i+=1 ))
done
# sleep 1
echo hello world >pipe
wait
Se diminuirmos o limite de 10 para 1, ele não trava (pelo menos não de forma confiável). Dormir impede que ele trave.
Acho que o eco está acontecendo antes de todos os trabalhos em segundo plano terem aberto o pipe, então o EOF é gravado no pipe, fechando o pipe e encerrando alguns trabalhos em segundo plano. Os que chegam atrasados ficam presos esperando por um EOF que nunca chega.
Esse é o comportamento esperado? Parece um bug para mim, mas não tenho certeza se é meu bug ou do shell.
Além disso: sei que posso simplesmente escrever echo x | { <launch commands here> }
, e isso seria mais organizado, mas estou trabalhando em um comportamento do traço que já relatei como um bug .
EDIT: A versão abaixo termina consistentemente no bash, então parece provável que a intenção seja iniciar um grupo de processos em segundo plano e alimentá-los a partir de um único pipeline sem fazer nada especial.
echo hello world | {
i=0
while [ $i -lt 10 ]; do
cat &
: $(( i+=1 ))
done
}
wait
EDIT: abrir o pipe no pai (modo r/w para evitar bloqueios ) e duplicar o descritor de arquivo resultante para cada processo em segundo plano não parece resolver o problema e resulta em travamentos mesmo após o modo de suspensão.
[ -p pipe ] || mkfifo pipe
exec 3<>pipe
i=0
while [ $i -lt 10 ]; do
<&3 cat &
: $(( i+=1 ))
done
# sleep 1
echo hello world >pipe
wait