Qual é o tempo de vida de um descritor de arquivo?

10

Conforme descrito aqui , os redirecionamentos usam open() para gravar em um arquivo. Há um descritor de arquivo interno (?) Criado no shell e, em seguida, usado quando necessário.

O descritor interno é criado para toda a duração do script ou para a duração da shell? É destruído depois de algum tempo, várias operações, etc?

Eu quero dizer, em particular, os descritores de arquivos para os arquivos que o próprio shell abre para suas operações internas. 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? Eu às vezes mantenho uma sessão aberta por dias, talvez até semanas. Será que ainda mantém os descritores para todos os arquivos que eu operava com built-ins de shell?

    
por Tomasz 18.05.2018 / 17:11

2 respostas

4

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" }'
    
por 19.05.2018 / 23:36
6

Eles estão fechados quando terminados. O shell criará 3 descritores de arquivo 0,1,2 para cada comando que for executado. Estes são apenas números, os números são reutilizados. O shell irá 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 arquivos.

O exemplo usa 3>&1 , isto significa que o descritor de arquivos 3 se refere ao arquivo que o descritor 1 atualmente se refere.

    
por 18.05.2018 / 17:37