Na verdade, é bem simples, pelo menos, se você não precisar dos detalhes da implementação.
Primeiramente, 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 do usuário através do FUSE, e alguns vêm apenas na forma de um módulo do kernel ( ZFS nativo é um exemplo notável deste último. devido a restrições de licenciamento), mas de qualquer forma permanece um componente do kernel. Este é um básico importante. Quando um programa deseja ler de um arquivo, ele emitirá várias chamadas de biblioteca do sistema que acabarão no kernel na forma de uma sequência open()
, read()
, close()
(possivelmente com seek()
jogado em boa medida). O kernel usa o caminho e o nome de arquivo fornecidos e, por meio 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 em atualizações de atime) para algum armazenamento subjacente. >
No entanto, não precisa traduzir essas solicitações especificamente para armazenamento físico, persistente . O contrato do kernel é que, ao emitir esse conjunto específico de chamadas do sistema,
Em /proc
é geralmente montado o que é conhecido como procfs
. Esse é um tipo especial de sistema de arquivos, mas como é um sistema de arquivos, não é diferente de, por exemplo, um sistema de arquivos ext3
montado em algum lugar. Assim, o pedido é passado 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, é a estrutura de dados do kernel, e procfs
fornece uma interface limpa e conveniente para acessá-los. Tenha em mente que o procfs de montagem em /proc
é simplesmente convenção; você poderia facilmente montá-lo em outro lugar. Na verdade, isso às vezes é feito, por exemplo, em jail chroot quando o processo em execução precisa acessar / proc por algum motivo.
Funciona da mesma forma se você escrever um valor em algum arquivo; no nível do kernel, isso se traduz em uma série de open()
, seek()
, write()
, close()
chamadas que novamente são passadas para o driver do sistema de arquivos; novamente, neste caso particular, o código procfs.
O motivo especial pelo qual você vê file
returning empty
é que muitos dos arquivos expostos por procfs são expostos com um tamanho de 0 bytes. O tamanho de 0 byte é provavelmente uma otimização em o 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 seria potencialmente muito caro). Indo pelos comentários a essa resposta, que você pode verificar em seu próprio sistema executando strace ou uma ferramenta semelhante, file
primeiro emite uma chamada stat()
para detectar quaisquer arquivos especiais e, em seguida, aproveita a oportunidade para o tamanho do arquivo é relatado como 0, aborta e relata o arquivo como vazio.
Esse comportamento é realmente documentado e pode ser substituído especificando -s
ou --special-files
na invocação file
, embora, conforme declarado na página de manual, possa ter efeitos colaterais. A citação abaixo é da página man 5.11 do arquivo BSD, datada de 17 de outubro de 2011.
Normally, file only attempts to read and determine the type of argument files which stat(2) reports are ordinary files. This prevents problems, because reading special files may have peculiar consequences. Specifying the
-s
option causes file to also read argument files which are block or character special files. This is useful for determining the filesystem types of the data in raw disk partitions, which are block special files. This option also causes file to disregard the file size as reported by stat(2) since on some systems it reports a zero size for raw disk partitions.