Resumidamente: Um shell quase certamente fechará descritores de arquivos relacionados a redirecionamentos imediatamente após o comando ser concluído.
Detalhes: Não há nenhuma menção explícita ao fechamento dos arquivos abertos por meio de redirecionamentos no POSIX (até onde eu posso ver). Mas não fechá-los imediatamente não seria muito útil.
As regras para o ambiente em que nenhum comando foi iniciado não permitem passando descritores de arquivos extras. O shell precisaria tomar cuidado para fechar qualquer fd extra que foi salvo ao iniciar um comando que não deveria tê-los.
Para os redirecionamentos de saída > filename
usuais, o arquivo precisaria ser truncado ao iniciar cada comando, mesmo se o descritor de arquivo fosse salvo. E qualquer descritor de arquivo salvo apontaria para um arquivo errado se o arquivo em questão fosse renomeado ou removido no meio tempo.
Por exemplo, isso não se comportaria corretamente se o fd aberto para o primeiro echo
fosse mantido aberto e usado como está para o segundo:
echo foo >> x; mv x y; echo bar >> x
O modelo fork + exec usual usado para iniciar programas externos também facilita muito ter os arquivos automaticamente
feche quando o comando sair. O shell precisa apenas de fork()
e abrir todos os arquivos necessários na criança
processo, antes de chamar exec()
para substituir o filho pelo comando real. Quando o processo filho sai, todos os arquivos abertos por ele são automaticamente fechados.
Em awk
, a sintaxe para o redirecionamento de saída é semelhante ao shell, mas os arquivos abertos são mantidos abertos até
o script sai, a menos que explicitamente fechado. Isso só abrirá foo
uma vez e não truncará entre as impressões:
awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'