Qual é a vida útil de um descritor de arquivo?

11

Conforme descrito aqui , os redirecionamentos costumam ser open()gravados em um arquivo. Existe um descritor de arquivo interno (?) Criado no shell e usado quando necessário.

O descritor interno é criado para toda a duração do script ou para a vida útil do shell? É destruído após algum tempo, várias operações, etc?

Quero dizer, em particular, descritores de arquivos para os arquivos que o próprio shell abre para as operações de seus componentes internos. O descritor é criado e o arquivo é aberto para cada operação? Quanto tempo eles são mantidos? Exemplo:

#!/bin/bash
>>x echo something
...do many other things not related to the file x
>>x echo something more

A primeira instância do descritor é mantida até a segunda operação?

E o shell que eu uso em um terminal? Às vezes, mantenho uma sessão aberta por dias, talvez até semanas. Ele ainda mantém os descritores de todos os arquivos em que eu operava com os shell incorporados?

Jeff Schaller
fonte

Respostas:

4

Resumidamente: Um shell quase certamente fechará descritores de arquivos relacionados a redirecionamentos imediatamente após a conclusão do comando.


Detalhes: Não há menção explícita ao fechar os arquivos abertos através de redirecionamentos no POSIX (tanto quanto posso ver). Mas não fechá-los imediatamente não seria muito útil.

As regras para o ambiente em que todos os comandos são iniciados não permitem passar descritores de arquivo extras. O shell precisaria ter o cuidado de fechar todos os dados extras salvos ao iniciar um comando que não deveria tê-los.

Para os > filenameredirecionamentos de saída usuais , o arquivo precisaria ser truncado ao iniciar cada comando, mesmo que o descritor de arquivo estivesse salvo. E qualquer descritor de arquivo salvo apontaria para um arquivo errado se o arquivo em questão fosse renomeado ou removido nesse meio tempo.

Por exemplo, isso não se comportaria corretamente se o fd aberto para o primeiro echofosse mantido aberto e usado como está no segundo:

echo foo >> x; mv x y; echo bar >> x

O modelo usual fork + exec usado para iniciar programas externos também facilita muito o fechamento automático dos arquivos quando o comando é encerrado. O shell precisa fork()primeiro e abrir todos os arquivos necessários no processo filho, antes de chamar exec()para substituir o filho pelo comando real. Quando o processo filho sai, todos os arquivos abertos por ele são fechados automaticamente.


Noawk entanto, a sintaxe para redirecionamento de saída é semelhante à casca, mas os arquivos abertos são mantidos abertos até as saídas de script, a menos que explicitamente fechado. Isso será aberto apenas uma foovez e não o truncará entre as impressões:

awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'
ilkkachu
fonte
6

Eles são fechados quando terminar. O shell criará 3 descritores de arquivo 0,1,2 para cada comando executado. Estes são apenas números, os números são reutilizados. O shell fechará os arquivos antes de reutilizar os descritores.

Os descritores de arquivo também são passados ​​para outros processos. E se você tiver um processo em segundo plano, ele ainda terá descritores de arquivo.

O exemplo usa 3>&1, isso significa fazer com que o descritor de arquivo 3 se refira ao arquivo ao qual o descritor 1 se refere atualmente.

ctrl-alt-delor
fonte