Na verdade, é bem simples, pelo menos se você não precisar dos detalhes da implementação.
Primeiro, no Linux todos os sistemas de arquivos (ext2, ext3, btrfs, reiserfs, tmpfs, zfs, ...) são implementados no kernel. Alguns podem descarregar o trabalho para o código da terra do usuário através do FUSE, e outros vêm apenas na forma de um módulo do kernel (o ZFS nativo é um exemplo notável deste último devido a restrições de licença), mas de qualquer forma permanece um componente do kernel. Este é um importante básico.
Quando um programa quer ler a partir de um arquivo, ele irá emitir várias chamadas de bibliotecas do sistema que finalmente acabam no kernel na forma de um open()
, read()
, close()
seqüência (possivelmente com seek()
jogado em boa medida). O kernel usa o caminho e o nome do arquivo fornecidos e, através do sistema de arquivos e da camada de E / S do dispositivo, os converte em solicitações de leitura física (e em muitos casos também solicitações de gravação - pense, por exemplo, atualizações atime) em algum armazenamento subjacente.
No entanto, ele não precisa converter essas solicitações especificamente para armazenamento físico persistente . O contrato do kernel é que a emissão desse conjunto específico de chamadas do sistema fornecerá o conteúdo do arquivo em questão . Onde exatamente em nosso domínio físico o "arquivo" existe é secundário a isso.
Em /proc
geralmente é montado o que é conhecido como procfs
. Esse é um tipo especial de sistema de arquivos, mas como é um sistema de arquivos, na verdade não é diferente de, por exemplo, um ext3
sistema de arquivos montado em algum lugar. Portanto, a solicitação é passada para o código do driver do sistema de arquivos procfs, que conhece todos esses arquivos e diretórios e retorna informações específicas das estruturas de dados do kernel .
A "camada de armazenamento", neste caso, são as estruturas de dados do kernel e procfs
fornece uma interface limpa e conveniente para acessá-las. Lembre-se de que montar procfs no /proc
é simplesmente uma convenção; você poderia facilmente montá-lo em outro lugar. De fato, isso às vezes é feito, por exemplo, nas cadeias chroot quando o processo em execução lá precisa acessar / proc por algum motivo.
Funciona da mesma maneira se você escrever um valor em algum arquivo; no nível do kernel, que se traduz em uma série de open()
, seek()
, write()
, close()
chamadas que novamente são passadas para o driver de sistema de arquivos; novamente, nesse caso em particular, o código procfs.
A razão específica pela qual você vê o file
retorno empty
é que muitos dos arquivos expostos pelo procfs são expostos com um tamanho de 0 bytes. O tamanho de 0 byte é provavelmente uma otimização no lado do kernel (muitos dos arquivos em / proc são dinâmicos e podem variar facilmente em comprimento, possivelmente até de uma leitura para a próxima, e calcular o tamanho de cada arquivo em cada diretório lido potencialmente muito caro). Indo pelos comentários a esta resposta, que você pode verificar em seu próprio sistema, executando o strace ou uma ferramenta semelhante, file
emite uma stat()
chamada para detectar arquivos especiais e, em seguida, aproveita a oportunidade para, se o tamanho do arquivo for 0 , anule e relate o arquivo como vazio.
Esse comportamento é realmente documentado e pode ser substituído, especificando -s
ou --special-files
na file
invocação, embora conforme declarado na página de manual que possa ter efeitos colaterais. A citação abaixo é da página do manual do arquivo BSD 5.11, de 17 de outubro de 2011.
Normalmente, o arquivo tenta apenas ler e determinar o tipo de arquivos de argumento que os relatórios stat (2) são arquivos comuns. Isso evita problemas, porque a leitura de arquivos especiais pode ter consequências peculiares. A especificação da -s
opção faz com que o arquivo também leia arquivos de argumento que são arquivos especiais de bloco ou caractere. Isso é útil para determinar os tipos de sistema de arquivos dos dados nas partições de disco bruto, que são arquivos especiais de bloco. Essa opção também faz com que o arquivo desconsidere o tamanho do arquivo, conforme relatado pelo stat (2), pois em alguns sistemas ele relata um tamanho zero para partições de disco bruto.
strace file /proc/version
oultrace -S /proc/version
, a otimização é bastante pequena. Ele faz umastat()
chamada primeiro e descobre que o tamanho é 0, pulando oopen()
- mas antes disso está carregando vários arquivos mágicos.