Tem a ver com o fechamento do descritor de arquivos.
No seu primeiro exemplo, echo grava em seu fluxo de saída padrão que o shell abre para conectá-lo com f e, quando ele termina, seu descritor é fechado (pelo shell). Na extremidade de recebimento, o shell, que lê a entrada de seu fluxo de entrada padrão (conectado a f ) lê ls , executa ls e, em seguida, termina devido à condição de fim de arquivo em sua entrada padrão. / p>
A condição de final de arquivo ocorre porque todos os escritores do canal nomeado (apenas um neste exemplo) fecharam o final do canal.
Em seu segundo exemplo, exec 3>f abre o descritor de arquivos 3 para gravar em f e, em seguida, echo escreve ls . É o shell que agora tem o descritor de arquivo aberto, não o comando echo . O descritor permanece aberto até você fazer exec 3>&- . Na extremidade de recepção, o shell, que lê a entrada de seu fluxo de entrada padrão (conectado a f ), lê ls , executa ls e aguarda por mais entrada (já que o fluxo ainda está aberto).
O fluxo permanece aberto porque todos os autores (shell, via exec 3>f e echo ) não fecharam o final do canal ( exec 3>f ainda está em vigor) .
Eu escrevi sobre echo acima como se fosse um comando externo. É mais provável que seja construído no shell. O efeito é o mesmo, no entanto.