Disk management: df, du, mount e fstab em automações

1. Introdução ao Gerenciamento de Discos em Scripts

Em ambientes Linux, o gerenciamento de discos é uma tarefa recorrente que, quando automatizada, reduz drasticamente o trabalho manual e previne falhas catastróficas como discos lotados ou montagens incorretas. Scripts em Bash permitem monitorar, montar, limpar e sincronizar sistemas de arquivos de forma confiável e repetível.

Os comandos essenciais para essa tarefa são:

  • df — relata o uso de espaço em sistemas de arquivos montados
  • du — estima o uso de espaço em diretórios e arquivos
  • mount — monta sistemas de arquivos manualmente
  • /etc/fstab — define montagens permanentes que ocorrem na inicialização

Cenários comuns incluem: alertas quando um disco atinge 90% de uso, backups que verificam espaço disponível antes de copiar dados, e montagem automática de discos externos para sincronização noturna.

2. Monitoramento de Espaço em Disco com df

O comando df é a ferramenta principal para verificar o espaço disponível em partições montadas. Para scripts, as opções -h (human-readable) e -T (tipo de sistema de arquivos) são particularmente úteis.

# Exemplo: listar todos os sistemas de arquivos com uso legível
df -hT

Para filtrar apenas partições específicas (ex: /dev/sda1), combinamos com grep:

# Filtrar partição específica
df -h | grep "/dev/sda1"

Um alerta automático de disco cheio pode ser implementado com awk e uma estrutura condicional:

#!/bin/bash
LIMITE=90
USO=$(df -h / | awk 'NR==2 {print $5}' | cut -d'%' -f1)
if [ "$USO" -gt "$LIMITE" ]; then
    echo "ALERTA: Partição raiz com $USO% de uso!" | mail -s "Disco Cheio" admin@exemplo.com
fi

O awk extrai o quinto campo da segunda linha (percentual de uso) e cut remove o caractere %. A comparação numérica com -gt dispara o alerta.

3. Análise de Diretórios com du

Enquanto df mostra o todo, du detalha o consumo por diretório. As opções -sh (sumário human-readable) e --max-depth controlam a profundidade da análise.

# Tamanho total de um diretório específico
du -sh /var/log

# Top 10 diretórios dentro de /home, ordenados por tamanho
du -h --max-depth=1 /home | sort -rh | head -10

Para automação de limpeza, podemos excluir arquivos antigos condicionalmente:

#!/bin/bash
DIR="/var/log/meu_app"
LIMITE=500  # em MB
USO_MB=$(du -sm "$DIR" | cut -f1)
if [ "$USO_MB" -gt "$LIMITE" ]; then
    echo "Removendo logs com mais de 7 dias em $DIR"
    find "$DIR" -type f -name "*.log" -mtime +7 -exec rm {} \;
fi

O comando du -sm retorna o tamanho em megabytes, permitindo comparação direta com o limite definido.

4. Montagem Automática com mount

Montar sistemas de arquivos manualmente em scripts requer cuidado. A sintaxe básica é:

# Montar um dispositivo
mount -t ext4 /dev/sdb1 /mnt/backup

Antes de montar, é prudente verificar se o ponto de montagem existe e se o dispositivo já está montado:

#!/bin/bash
DISPOSITIVO="/dev/sdb1"
PONTO="/mnt/backup"

# Verificar se o ponto de montagem existe
if [ ! -d "$PONTO" ]; then
    mkdir -p "$PONTO"
fi

# Verificar se já está montado
if mount | grep -q "$DISPOSITIVO"; then
    echo "Dispositivo já montado em $PONTO"
else
    mount "$DISPOSITIVO" "$PONTO" && echo "Montagem bem-sucedida" || echo "Falha na montagem"
fi

O grep -q (quiet) retorna código 0 se encontrar correspondência, permitindo a tomada de decisão no if.

5. Gerenciamento de Montagens Persistentes com /etc/fstab

O arquivo /etc/fstab define montagens automáticas na inicialização. Cada linha possui seis campos:

# <dispositivo>  <ponto>  <tipo>  <opções>  <dump>  <pass>
/dev/sdb1       /mnt/backup ext4    defaults   0       2

Para ler e validar entradas via script:

# Verificar se uma entrada específica existe no fstab
grep "/mnt/backup" /etc/fstab

# Extrair o dispositivo associado a um ponto de montagem
awk '$2 == "/mnt/backup" {print $1}' /etc/fstab

Adicionar uma nova entrada programaticamente requer cuidado com permissões (root) e formatação:

#!/bin/bash
echo "/dev/sdc1 /mnt/dados ext4 defaults 0 2" >> /etc/fstab
mount -a  # monta todas as entradas do fstab

Para remover, usamos sed:

sed -i '/\/mnt\/dados/d' /etc/fstab

Sempre valide a sintaxe do fstab antes de reiniciar, com mount -a ou findmnt --verify.

6. Automação de Backup e Sincronização

Combinar df e du antes de backups evita interrupções por falta de espaço. Exemplo com rsync:

#!/bin/bash
ORIGEM="/dados/importantes"
DESTINO="/mnt/backup"
TAMANHO_ORIGEM=$(du -sb "$ORIGEM" | cut -f1)
ESPACO_LIVRE=$(df -B1 "$DESTINO" | awk 'NR==2 {print $4}')

if [ "$ESPACO_LIVRE" -gt "$TAMANHO_ORIGEM" ]; then
    mount "$DESTINO" 2>/dev/null || true
    rsync -av --delete "$ORIGEM" "$DESTINO" && echo "Backup concluído"
    umount "$DESTINO"
else
    echo "ERRO: Espaço insuficiente em $DESTINO" >&2
    exit 1
fi

A desmontagem segura com umount deve ser acompanhada de verificação:

if ! umount "$DESTINO"; then
    echo "Falha ao desmontar $DESTINO — processo pode estar usando o ponto" | logger
fi

7. Tratamento de Erros e Logs

Operações de disco podem falhar por diversos motivos: dispositivo ocupado, permissões, sistema de arquivos corrompido. Verificar $? é essencial:

mount /dev/sdb1 /mnt/backup
if [ $? -ne 0 ]; then
    echo "$(date): Falha ao montar /dev/sdb1" >> /var/log/disk_management.log
    logger -p user.err "Falha na montagem do disco de backup"
fi

Para logs estruturados, use timestamps e redirecionamento:

exec >> /var/log/disk_management.log 2>&1
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Iniciando rotina de limpeza"

Notificações podem ser enviadas por e-mail ou syslog:

# Notificação por e-mail
echo "Disco /dev/sda1 com 95% de uso" | mail -s "Alerta de Disco" admin@exemplo.com

# Notificação via syslog
logger -p local0.warning "Uso crítico de disco em /dev/sda1"

8. Exemplo Prático: Script Completo de Gerenciamento

Abaixo, um script que integra monitoramento, montagem e limpeza, pronto para ser executado via cron:

#!/bin/bash
# Script: gerenciamento_discos.sh
# Uso: ./gerenciamento_discos.sh

LOGFILE="/var/log/disk_management.log"
LIMITE_DF=85
LIMITE_DU=500  # MB
DIR_LOG="/var/log/meu_app"
PONTO_BACKUP="/mnt/backup"
DISPOSITIVO_BACKUP="/dev/sdb1"

exec >> "$LOGFILE" 2>&1

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

monitorar_espaco() {
    log "Monitorando espaço em disco..."
    USO=$(df -h / | awk 'NR==2 {print $5}' | cut -d'%' -f1)
    if [ "$USO" -gt "$LIMITE_DF" ]; then
        log "ALERTA: Partição raiz com $USO% de uso"
        echo "Partição raiz com $USO% de uso" | mail -s "Alerta de Disco" admin@exemplo.com
    fi
}

limpar_logs() {
    log "Verificando tamanho de $DIR_LOG..."
    USO_MB=$(du -sm "$DIR_LOG" 2>/dev/null | cut -f1)
    if [ -n "$USO_MB" ] && [ "$USO_MB" -gt "$LIMITE_DU" ]; then
        log "Removendo logs com mais de 7 dias de $DIR_LOG"
        find "$DIR_LOG" -type f -name "*.log" -mtime +7 -exec rm {} \;
        log "Limpeza concluída. Novo tamanho: $(du -sh "$DIR_LOG" | cut -f1)"
    fi
}

montar_backup() {
    log "Montando $DISPOSITIVO_BACKUP em $PONTO_BACKUP..."
    if [ ! -d "$PONTO_BACKUP" ]; then
        mkdir -p "$PONTO_BACKUP"
    fi
    if mount | grep -q "$DISPOSITIVO_BACKUP"; then
        log "Dispositivo já montado"
    else
        mount "$DISPOSITIVO_BACKUP" "$PONTO_BACKUP"
        if [ $? -eq 0 ]; then
            log "Montagem bem-sucedida"
        else
            log "ERRO: Falha na montagem"
            return 1
        fi
    fi
}

desmontar_backup() {
    log "Desmontando $PONTO_BACKUP..."
    umount "$PONTO_BACKUP"
    if [ $? -eq 0 ]; then
        log "Desmontagem bem-sucedida"
    else
        log "ERRO: Falha ao desmontar — ponto ainda em uso"
    fi
}

# Execução principal
log "=== Iniciando rotina ==="
monitorar_espaco
limpar_logs
montar_backup
# Aqui poderia vir um rsync, se necessário
sleep 2
desmontar_backup
log "=== Rotina concluída ==="

Para executar periodicamente, adicione ao crontab:

# Executar todo dia às 2h da manhã
0 2 * * * /usr/local/bin/gerenciamento_discos.sh

Considerações de segurança: scripts que manipulam discos geralmente exigem execução como root. Use sudo com cuidado e restrinja permissões do script (chmod 700). Nunca exponha senhas ou chaves SSH diretamente no script — prefira variáveis de ambiente ou arquivos de configuração protegidos.


Referências