Como visualizar o tamanho de diretórios no Linux

(Last Updated On: 1 de dezembro de 2017)

Aqui na Alura temos um servidor para guardar alguns arquivos e projetos internos, que basicamente funciona como um repositório interno.

Esse servidor tem um espaço de armazenamento limitado e, de tempos em tempos, tenho que ficar conferindo se a pasta do compartilhamento está ficando muito cheia.

O servidor não possuí modo gráfico, então como posso saber o tamanho da pasta de compartilhamento?

Descobrindo o tamanho de um diretório

Para descobrir quanto do disco que o diretório está usando basta ir até o terminal e dizer: “por favor, mostre-me o quanto do disco (du, disk usage) o diretório /compartilhamento está usando”:

du /compartilhamento/

Conseguimos a informação! Mas para isso o terminal mostrou o tamanho de todos os arquivos e subpastas e só na última mostrou um resumo do diretório. Nós precisamos apenas desta última linha, existe algum jeito de obtermos somente ela?

Bem, queremos que o programa resuma sua saída e nos mostre apenas o total no diretório. Como queremos que ele sintetizar (-s, summarize) a informação:

du -s /compartilhamento/

Veja que agora conseguimos apenas a informação que queríamos. Mas o que significa esse número?

A saída padrão do comando du mostra os números em kilobytes. Só que esse número não fica muito compreensível para nós, precisamos deixá-lo mais inteligível para humanos (-h).

Podemos utilizar as duas expressões separadamente, -s -h, ou juntas -sh:

du -sh /compartilhamento/

Ótimo! Conseguimos visualizar o tamanho do nosso diretório, mas quanto isso ocupa no no disco?

Para saber o quanto do disco está sendo usado, utilizamos outro comando: df .Este retorna o espaço livre, ou ocupado, de cada partição no sistema.

df

Da mesma forma que fazemos com o du, podemos especificar o diretório, assim, ele retorna somente a partição da qual esse diretório pertence. Podemos também utilizar a opção -h e teremos uma saída mais legível.

df -h /compartilhamento/

Notaram que os valores das saídas dos comandos foram diferentes? Isso porque o du lista apenas os arquivos e pastas que estão contidos no diretório. Já o df, lista a partição, junto com o sistemas de arquivos da mesma.

Hum… Mas dessa forma preciso ficar checando esses dois comandos todos os dias. Existe alguma maneira de automatizar essa tarefa para que, quando esse diretório estiver perto de encher, eu receba uma mensagem?

Criando o código

Podemos automatizar essa tarefa criando um script que o Linux interpretará de tempos em tempos.

Bem, queremos checar o tamanho do diretório, então vamos nomear nosso script com algo que nos lembre isso. No meu caso vou chamar de consulta_tamanho_diretorio.

Podemos especificar dizendo que é um arquivo Shell com a extensão .sh, mas se não colocarmos, o sistema consegue rodá-lo da mesma maneira.

Existem vários tipos de Shell (Bash, Bourne Shell, Korn Shell), cada um com suas diferenças. Para nosso script saber qual deles utilizar, temos que especificá-los na primeira linha.

Um dos shells mais utilizados é o Bash, vamos utilizá-lo. Logo na primeira linha digitamos:

#!/bin/bash

Como queremos visualizar a tamanho ocupado pelo diretório /compartilhamento, temos que fazer nosso script acessá-lo. Portanto: cd /compartilhamento


#!/bin/bash
cd /compartilhamento

Agora temos que pegar a informação sobre o tamanho do diretório. Já vimos como fazer isso, basta atribuirmos esse valor a uma variável.

O comando que nos retorna o percentual é o df, como queremos saber apenas do diretório compartilhamento, é ele que vamos especificar, já que queremos apenas a informação da porcentagem, não precisamos colocar o parâmetro -h


#!/bin/bash
cd /compartilhamento
uso_do_diretorio=$(df /compartilhamento)

Só que, como vimos, esse comando nos retorna duas linhas, a primeira é um cabeçalho, enquanto a segunda são as informações sobre a partição.

Queremos apenas a informação sobre o uso, que se encontra na coluna 5:

Para conseguir obtê-la, podemos redirecionar a saída do comando df para o comando awk. Como queremos a quinta coluna, falamos para o awk imprimi-lo: awk {'print $5'}


#!/bin/bash
cd /compartilhamento
uso_do_diretorio=$(df /compartilhamento | awk {'print $5'})

Vamos testar essa parte do nosso script. Para isso, imprimimos na tela a variável uso_do_diretorio utilizando o echo $uso_do_diretorio


#!/bin/bash
cd /compartilhamento
uso_do_diretorio=$(df /compartilhamento | awk {'print $5'})
echo $uso_do_diretorio

Hum, funcionou, mas essa variável deveria conter apenas o valor da porcentagem, existe alguma maneira de capturá-lo?

Da mesma forma que usamos para retirar essa informação o comando df. Podemos imprimir essa variável e capturar sua segunda informação.

Basta imprimir a variável, e usar o awk para capturar o parâmetro desejado.

Logo, voltamos ao nosso código e digitamos:


#!/bin/bash
cd /compartilhamento
uso_do_diretorio=$(df /compartilhamento | awk {'print $5'})
percentual=$(echo $uso_do_diretorio | awk {'print $2'})

Vamos testar novamente nosso código falando para ele imprimir essa variável:


#Restante do código omitido
echo $percentual

Uhu! Conseguimos! Agora temos que checar se nossa variável percentual está próxima do 100%. Se sim, podemos escrever uma mensagem avisando que o armazenamento está se esgotando.

Checando a variável

Se (if) nossa variável estiver com 70% ou mais, então (then) vamos escrever uma mensagem na tela.

Para realizar essa comparação, vamos utilizar algumas expressões regulares. Nossa variável pode ter valores de 70% até 100%, ou seja, o dígito da dezena pode variar de 7 a 9 ([7-9]) e o da unidade de 0 a 9 ([0-9]), seguido do símbolo de percentual (%).

Essa expressão captura valores de 70% até 99%. Para acrescentarmos o 100%, dizemos que ou é essa expressão ([7-9][0-9]%), ou (|) será utilizado 100% para realizar a comparação.

A expressão completa fica assim:

[7-9][0-9]%|100%

Basta informar essa condição em nosso if:


#Restante do código omitido
if [[ $percentual =~ [7-9][0-9]%$|100% ]]; then
        echo "ATENÇÃO - O espaço de armazenamento está ficando cheio"
fi

Vamos testar nosso script e checar se está funcionando:

Bacana! Está funcionando! Mas dessa maneira, não conseguimos ter um histórico das mensagens. Podemos salvar essa mensagem em um arquivo de log, assim conseguiríamos manter esse histórico.

Para colocar essa informação dentro de um arquivo, na linha onde ele imprime na tela a mensagem, iremos pegá-la e direcioná-la (>>) para o arquivo onde ficará nosso log que, no meu caso, fica em /logs/compartilhamento.log.



#Restante do código omitido
if [[ $percentual =~ [7-9][0-9]%$|100% ]]; then

        echo "ATENÇÃO - O espaço de armazenamento está ficando cheio" >> /logs/compartilhamento.log
fi

O bacana é que mesmo que esse arquivo não exista, o programa o cria. Vamos testar nosso código novamente:

Legal! Está funcionando! Mas quando conseguiremos saber quando essa informação foi inserida no arquivo? Junto com a mensagem, podemos colocar a informação da data e hora da inserção, vamos acrescentá-las?

Acrescentando data e hora

Para salvar a data no arquivo podemos utilizar o comando date. Este comando pode alterar ou exibir a data e hora do sistema.

Para imprimir a data do sistema, utilizamos o parâmetro %F (Full Date), como é o primeiro parâmetro, colocamos um + na frente, ficando +%F. Esse parâmetro mostra a data do sistema no formato ano-mês-dia.

Vamos acrescentar o parâmetro para mostrar as horas , minutos e segundos, podemos utilizar %T (Time):

date +%F %T

Hum… por que não funcionou?

Quando damos espaço entre os parâmetros, o date não reconhece os que vem após esse espaço. Para resolver esse problema, basta escapar (\) esse espaço:

date +%F\ %T

Agora sim! Conseguimos a informação de data e hora, vamos acrescentá-las em nosso script:


#Restante do código omitido
if [[ $percentual =~ [7-9][0-9]%$|100% ]]; then
        echo "ATENÇÃO - O espaço de armazenamento está ficando cheio $(date +%F\ %T)" >> /logs/compartilhamento.log
fi

Agora nosso arquivo terá a informação de data e hora:

Primeira parte concluída! Agora precisamos executar esse arquivo de tempos em tempos. No Linux já existe um utilitário para isso, chamado cron.

Agendando tarefas

Podemos agendar tarefas no cron para elas serem executadas de dias em dias, horas em horas, a cada minuto, enfim da maneira que for melhor para cada situação. Para colocar essa tarefa como automática, temos que editar o arquivo do cron. Portanto, no terminal:

crontab -e

O arquivo do cron é dividido em sete colunas. Minutos, horas, dias do mês, mês, dias da semana, usuário e o comando a ser executado. Cada uma dessas colunas podem receber diferentes valores.

No nosso caso, queremos que esse script seja executado a cada hora. Por isso, na primeira coluna, a dos minutos, colocamos o valor 0, as demais colocamos * (asterisco).

Dessa forma, cada vez que o minuto for 00, ou seja, a cada hora, será executado o comando.

O usuário que irá executar o comando é, no nosso caso, o superusuário (root), como ele é o mesmo usuário que criou o arquivo, não precisamos especificá-lo. E o comando será: bash consulta_tamanho_diretorio.sh

Vale lembrar que se o script estiver em outro diretório sem ser o do usuário que irá executá-lo, devemos especificar o caminho até ele.

0 * * * * bash consulta_tamanho_diretorio.sh

Para salvar e sair do arquivo de configuração do cron, pressionamos Esc e depois digitamos :x.

“Mas por que não colocar asterisco em todas as colunas? Assim nosso script não seria executado a todo momento?”

Sim. Dessa forma a cada minuto o script seria executado, porém isso poderia, dependendo do número de requisições que o servidor recebe, sobrecarregaria sua CPU.

Agora nosso arquivo de log sempre será atualizado sobre essa informação. 🙂

Vamos olhar o arquivo de log e ver se ele está inserindo a informação:

Para saber mais

Esse foi apenas um uso exemplo de como usamos Shell Script. Além de escrever essa informação no diretório, poderíamos enviar um e-mail para o administrador do sistema, poderíamos aumentar automaticamente o tamanho do da partição.

Podíamos também criar um script que recebesse como parâmetro o nome do diretório.

Nesse caso eu utilizei o superusuário (root) para fazer as configurações, mas podemos utilizar qualquer usuário para criar os scripts.

Caso você esteja utilizando o usuário root para fazer os scripts cuidado para não executar um script que comprometa o sistema.

Problema Resolvido

Tínhamos que ficar checando de tempos em tempos se o diretório de compartilhamento estava ficando cheio. Vimos como podemos fazer isso e como automatizar essa tarefa utilizando Shell Script utilizando o cron para agendá-la.

E aí, o que achou? Já conhecia essas técnicas? Conhece outras? Compartilhe conosco nos comentários. 🙂

Gostou de Shell Script? Aqui na Alura temos um curso sobre. Nele você aprenderá como automatizar tarefas utilizando o Shell Script, como criar estruturas de seleção e repetição, funções e muito mais!

FIQUE POR DENTRO

  • Alan Soder

    Olá Yuri.
    Ao utilizar o awk pela primeira vez e imprimir a 5° posição, o texto “Disponível 77%” foi impresso. Por que o texto “Disponível” apareceu ? ele é da quarta posição, não?

    • Yuri Oliveira

      Olá Alan, tudo bem?

      O awk por padrão utiliza os espaços em branco para dividir as colunas.

      Como no caso desta tabela, o primeiro nome Sist. Arq. tem um espaço separando as palavras, ele conta, neste caso do cabeçalho, como duas colunas diferentes.

      Sist. como sendo a primeira e Arq. como sendo a segunda. Por isso Disponível fica na quinta posição.

      • Alan Soder

        Tudo bem sim, Yuri!

        Muito obrigado pela explicação e parabéns, ótimo artigo!

        • Yuri Oliveira

          Muito obrigado pelo feedback Alan! 😀

  • NM

    No dia a dia também costumo usar:
    # du -shc *

    • Yuri Oliveira

      Sim, dependendo da situação esse comando pode ser muito útil.

  • Excelente artigo e ótima introdução para termos a mente de automatizar tarefas!!!

    Sugestão de correção de digitação. De “O servidor não possí modo gráfico” para “O servidor não possui modo gráfico”

    • Yuri Oliveira

      Muito obrigado pelo feedback Mateus!

      Erro corrigido, obrigado. 😀

Próximo ArtigoDesenvolvimento de jogos em Lua