Domine o comando `stat` no Linux: guia completo com dicas e truques!

O utilitário stat no Linux oferece uma visão muito mais detalhada do que o comando ls. Vamos explorar este recurso informativo e altamente configurável para entender melhor como ele funciona e como tirar proveito de suas funcionalidades.

Descobrindo os Bastidores com o Comando stat

Embora o comando ls seja extremamente útil e execute sua função com maestria, no universo Linux, sempre existe a possibilidade de aprofundar a investigação e desvendar o que se esconde sob a superfície. E frequentemente, isso não se limita a levantar uma ponta do tapete; podemos, na verdade, remover as tábuas do assoalho e cavar mais fundo. É como descascar uma cebola, camada por camada.

O ls consegue fornecer informações valiosas sobre um arquivo, como suas permissões, tamanho e se é um arquivo comum ou um link simbólico. Para exibir essas informações, o ls acessa uma estrutura do sistema de arquivos chamada inode.

Cada arquivo e diretório possui um inode. Este inode armazena metadados sobre o arquivo, incluindo os blocos do sistema de arquivos que ele ocupa e os carimbos de data/hora associados. O inode funciona como um cartão de registro do arquivo. No entanto, o ls exibe apenas uma parcela dessas informações. Para ter uma visão completa, precisamos utilizar o comando stat.

Assim como o ls, o comando stat dispõe de uma variedade de opções. Isso o torna um forte candidato para o uso de apelidos (aliases). Depois de identificar um conjunto específico de opções que faz com que o stat produza a saída desejada, é possível encapsulá-lo em um apelido ou função shell. Isso torna seu uso muito mais prático e elimina a necessidade de memorizar sequências complexas de opções.

Comparação Rápida entre ls e stat

Vamos usar o comando ls para gerar uma listagem longa (opção -l) com tamanhos de arquivos em formato legível (opção -h):

ls -lh ana.h

As informações apresentadas pelo ls, da esquerda para a direita, são:

  • O primeiro caractere, um hífen “-“, indica que o arquivo é um arquivo regular, e não um socket, link simbólico ou outro tipo de objeto.
  • As permissões de proprietário, grupo e outros são listadas no formato octal.
  • O número de links físicos que apontam para este arquivo. Na maioria dos casos, este valor será um.
  • O proprietário do arquivo, neste caso, é “dave”.
  • O grupo proprietário também é “dave”.
  • O tamanho do arquivo é de 802 bytes.
  • A última modificação do arquivo ocorreu na sexta-feira, 13 de dezembro de 2015.
  • O nome do arquivo é ana.c.

Agora, vamos usar o comando stat para visualizar as mesmas informações:

stat ana.h

As informações fornecidas pelo comando stat são:

  • Arquivo: O nome do arquivo. Geralmente, é o mesmo nome que passamos para o comando stat na linha de comando, mas pode ser diferente quando analisamos um link simbólico.
  • Tamanho: O tamanho do arquivo em bytes.
  • Blocos: O número de blocos do sistema de arquivos necessários para armazenar o arquivo no disco rígido.
  • Bloco IO: O tamanho de um bloco do sistema de arquivos.
  • Tipo de arquivo: O tipo de objeto que os metadados descrevem. Os tipos mais comuns são arquivos e diretórios, mas também podem ser links, sockets ou pipes nomeados.
  • Dispositivo: O número do dispositivo em hexadecimal e decimal. É o ID do disco rígido onde o arquivo está armazenado.
  • Inode: O número do inode. Este é o número de identificação deste inode. Juntos, o número do inode e o número do dispositivo identificam exclusivamente um arquivo.
  • Links: Indica quantos links físicos apontam para este arquivo. Cada link físico possui seu próprio inode. Portanto, outra maneira de entender este número é quantos inodes apontam para este arquivo. Cada vez que um link físico é criado ou excluído, esse número é ajustado. Quando chega a zero, o arquivo é excluído e o inode é removido. Se você usar stat em um diretório, este número representa a quantidade de arquivos no diretório, incluindo “.” para o diretório atual e “..” para o diretório pai.
  • Acesso: As permissões de arquivo são mostradas em formato octal e no formato tradicional rwx (read, write, execute).
  • Uid: O ID do usuário e o nome da conta do proprietário.
  • Gid: O ID do grupo e o nome da conta do proprietário.
  • Acesso: O carimbo de data/hora de acesso. Não é tão simples quanto parece. Distribuições Linux modernas usam um esquema chamado “relatime”, que tenta otimizar as gravações do disco rígido necessárias para atualizar o tempo de acesso. Resumidamente, o tempo de acesso é atualizado se for mais antigo do que o tempo de modificação.
  • Modificar: O carimbo de data/hora de modificação. Indica quando o conteúdo do arquivo foi alterado pela última vez.
  • Mudança: O carimbo de data/hora de alteração. Indica quando os atributos ou o conteúdo do arquivo foram alterados pela última vez. Se você modificar um arquivo definindo novas permissões, o carimbo de alteração será atualizado (porque os atributos do arquivo foram alterados), mas o carimbo de modificação não será (porque o conteúdo do arquivo não mudou).
  • Nascimento: Reservado para mostrar a data de criação original do arquivo, mas não é implementado no Linux.

Entendendo os Carimbos de Data/Hora

Os carimbos de data/hora são sensíveis ao fuso horário. O “-0500” no final de cada linha mostra que este arquivo foi criado em um computador em um fuso horário Tempo Universal Coordenado (UTC), cinco horas adiantado em relação ao fuso horário do computador atual. Isso significa que o computador atual está cinco horas atrasado em relação ao computador que criou o arquivo. Na verdade, o arquivo foi criado em um computador no fuso horário do Reino Unido e estamos examinando-o em um computador no fuso horário padrão oriental dos Estados Unidos.

Os carimbos de data/hora de modificação e alteração podem gerar confusão, pois, para os não iniciados, seus nomes parecem ter o mesmo significado.

Vamos utilizar o comando chmod para modificar as permissões de um arquivo chamado ana.c. Vamos torná-lo gravável por todos. Isso não afetará o conteúdo do arquivo, mas alterará seus atributos.

chmod +w ana.c

Em seguida, usaremos o stat para visualizar os carimbos de data/hora:

stat ana.c

O carimbo de data/hora de alteração foi atualizado, mas o de modificação não.

O carimbo de data/hora de modificação só é atualizado quando o conteúdo do arquivo é alterado. O carimbo de alteração é atualizado tanto para alterações de conteúdo quanto de atributos.

Utilizando stat com Múltiplos Arquivos

Para gerar um relatório de status sobre vários arquivos de uma só vez, basta passar seus nomes para o comando stat na linha de comando:

stat ana.h ana.o

Para utilizar o stat em um conjunto de arquivos, use o recurso de correspondência de padrões. O ponto de interrogação “?” representa qualquer caractere único, enquanto o asterisco “*” representa qualquer sequência de caracteres. Podemos instruir o stat para gerar relatórios sobre qualquer arquivo chamado “ana” com uma extensão de uma única letra utilizando o seguinte comando:

stat ana.?

Usando stat para Relatar Sistemas de Arquivos

O comando stat também pode gerar relatórios sobre o status dos sistemas de arquivos, além do status dos arquivos. A opção -f (filesystem) direciona o stat para gerar informações sobre o sistema de arquivos onde o arquivo reside. Observe que podemos passar um diretório como “/” para o stat em vez de um nome de arquivo.

stat -f ana.c

As informações que o comando stat fornece são:

  • Arquivo: O nome do arquivo.
  • ID: O ID do sistema de arquivos em notação hexadecimal.
  • Namelen: O comprimento máximo permitido para nomes de arquivo.
  • Tipo: O tipo de sistema de arquivos.
  • Tamanho do bloco: A quantidade de dados solicitados nas operações de leitura para otimizar as taxas de transferência de dados.
  • Tamanho do bloco fundamental: O tamanho de cada bloco do sistema de arquivos.

Blocos:

  • Total: A contagem total de todos os blocos no sistema de arquivos.
  • Livre: O número de blocos livres no sistema de arquivos.
  • Disponíveis: O número de blocos livres disponíveis para usuários regulares (não root).

Inodes:

  • Total: A contagem total de inodes no sistema de arquivos.
  • Livre: O número de inodes livres no sistema de arquivos.

Desreferenciando Links Simbólicos

Se você usar o comando stat em um arquivo que seja, na verdade, um link simbólico, ele reportará informações sobre o link. Se você quiser que o stat reporte sobre o arquivo para o qual o link aponta, use a opção -L (dereference). O arquivo code.c é um link simbólico para ana.c. Vamos analisar sem a opção -L:

stat code.c

O nome do arquivo mostra code.c apontando para (->) ana.c. O tamanho do arquivo é de apenas 11 bytes. Não há blocos dedicados para armazenar este link. O tipo do arquivo é listado como um link simbólico.

Claramente, não estamos visualizando o arquivo real aqui. Vamos repetir a operação e adicionar a opção -L:

stat -L code.c

Agora, o comando está exibindo os detalhes do arquivo apontado pelo link simbólico. Note que o nome do arquivo ainda é apresentado como code.c. Esse é o nome do link, e não do arquivo de destino. Isso ocorre porque esse é o nome que passamos para o comando stat na linha de comando.

O Relatório Conciso

A opção -t (terse) faz com que o stat forneça um resumo condensado:

stat -t ana.c

Não há dicas fornecidas. Para entender – até que você memorize a sequência de campos – você precisará comparar essa saída com uma saída completa do stat.

Formatos de Saída Personalizados

A melhor maneira de obter um conjunto diferente de dados do stat é utilizar um formato personalizado. Existe uma longa lista de tokens chamados sequências de formato. Cada um representa um elemento de dado. Você pode selecionar aqueles que deseja incluir na saída e criar uma string de formato. Quando executamos o comando stat e passamos a string de formato para ele, a saída incluirá apenas os elementos de dado que solicitamos.

Existem diferentes conjuntos de sequências de formato para arquivos e sistemas de arquivos. A lista para arquivos é:

  • %a: Os direitos de acesso em octal.
  • %A: Os direitos de acesso em formato legível (rwx).
  • %b: O número de blocos alocados.
  • %B: O tamanho em bytes de cada bloco.
  • %d: O número do dispositivo em decimal.
  • %D: O número do dispositivo em hexadecimal.
  • %f: O modo bruto em hexadecimal.
  • %F: O tipo de arquivo.
  • %g: O ID de grupo do proprietário.
  • %G: O nome do grupo do proprietário.
  • %h: O número de links físicos.
  • %i: O número do inode.
  • %m: O ponto de montagem.
  • %n: O nome do arquivo.
  • %N: O nome do arquivo entre aspas, com o nome do arquivo não referenciado se for um link simbólico.
  • %o: A dica de tamanho de transferência de E/S ideal.
  • %s: O tamanho total, em bytes.
  • %t: O tipo principal de dispositivo em hexadecimal, para arquivos especiais de dispositivo de caractere/bloco.
  • %T: O tipo de dispositivo secundário em hexadecimal, para arquivos especiais de dispositivo de caractere/bloco.
  • %u: O ID de usuário do proprietário.
  • %U: O nome do usuário do proprietário.
  • %w: A hora de nascimento do arquivo, legível ou um hífen “-” se desconhecido.
  • %W: A hora de nascimento do arquivo, segundos desde a época; 0 se desconhecido.
  • %x: A hora do último acesso, legível por humanos.
  • %X: A hora do último acesso, segundos desde a época.
  • %y: A hora da última modificação de dados, legível por humanos.
  • %Y: A hora da última modificação de dados, segundos desde a época.
  • %z: A hora da última mudança de status, legível por humanos.
  • %Z: A hora da última mudança de status, segundos desde a época.

A “época” é a Época Unix, que ocorreu em 01/01/1970 00:00:00 +0000 (UTC).

Para sistemas de arquivos, as sequências de formato são:

  • %a: O número de blocos livres disponíveis para usuários regulares (não root).
  • %b: O total de blocos de dados no sistema de arquivos.
  • %c: O total de inodes no sistema de arquivos.
  • %d: O número de inodes livres no sistema de arquivos.
  • %f: O número de blocos livres no sistema de arquivos.
  • %i: O ID do sistema de arquivos em hexadecimal.
  • %l: O comprimento máximo dos nomes de arquivo.
  • %n: O nome do arquivo.
  • %s: O tamanho do bloco (o tamanho ideal para escrita).
  • %S: O tamanho dos blocos do sistema de arquivos (para contagens de blocos).
  • %t: O tipo de sistema de arquivos em hexadecimal.
  • %T: O tipo de sistema de arquivos em formato legível por humanos.

Existem duas opções que aceitam strings de sequências de formato. São elas: --format e --printf. A diferença entre elas é que --printf interpreta sequências de escape no estilo C, como quebra de linha \n e tabulação \t, e não adiciona automaticamente um caractere de nova linha à sua saída.

Vamos criar uma string de formato e passá-la para o comando stat. As sequências de formato a serem usadas são %n para o nome do arquivo, %s para o tamanho do arquivo e %F para o tipo de arquivo. Vamos adicionar a sequência de escape \n ao final da string para garantir que cada arquivo seja processado em uma nova linha. Nossa string de formato se parece com isso:

"Arquivo %n tem %s bytes e é um %F\n"

Vamos passar isso para o stat usando a opção --printf. Vamos solicitar que o stat gere um relatório sobre o arquivo chamado code.c e um conjunto de arquivos que correspondem a ana.?. Este é o comando completo. Note o sinal de igual “=” entre --printf e a string de formato:

stat --printf="Arquivo %n tem %s bytes e é um %F\n" code.c ana/ana.?

O relatório de cada arquivo é listado em uma nova linha, que é o que solicitamos. O nome do arquivo, tamanho e tipo são fornecidos.

Formatos personalizados fornecem acesso a ainda mais elementos de dado do que aqueles incluídos na saída padrão do stat.

Controle Detalhado

Como você pode observar, há um enorme escopo para extrair os elementos de dado específicos que são de seu interesse. É fácil entender por que recomendamos o uso de apelidos para os comandos mais longos e complexos.