Sim, é exatamente o que acontece:
$ mkfifo p
$ while :; do cat p ; done > /dev/null &
$ strace -etrace=open,close bash -c 'echo -n foo > p; echo bar > p' |& grep '"p"' -A1
open("p", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3) = 0
--
open("p", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3) = 0
Os redirecionamentos só entram em vigor pela duração do comando único em que estão configurados. A solução alternativa no lado da escrita é a) usar um bloco composto para agrupar os comandos, ou b) usar exec
para abrir um descritor de arquivo pela duração de todo o script (ou até fechado).
a)
{ echo -n foo; echo bar; } > p
(Você também pode colocar os comandos em uma função e usar o redirecionamento ao chamar a função.)
b)
exec 3>p
echo -n foo >&3
echo bar >&3
exec 3>&- # to explicitly close it
Se você quiser corrigi-lo no lado da leitura, será necessário executar um loop por read
e concatenar as strings obtidas. Como você deseja explicitamente as não-linhas parciais e ignora as condições de fim de arquivo, não é possível usar o código de saída de read
para algo útil.