Como criar scripts Bash úteis para tarefas diárias

1. Fundamentos de scripts Bash eficientes

Todo script Bash começa com o shebang #!/bin/bash na primeira linha, que indica ao sistema qual interpretador usar. Após criar o arquivo, é necessário torná-lo executável com chmod +x script.sh. Boas práticas incluem nomear arquivos com extensão .sh, organizar funções no início do script e usar indentação consistente.

O uso de variáveis locais com local dentro de funções evita poluição do escopo global. Armadilhas comuns incluem esquecer de escapar variáveis entre aspas duplas e assumir que variáveis não definidas têm valor vazio (quando na verdade podem causar erros).

#!/bin/bash
set -euo pipefail

log_erro() {
    local mensagem="$1"
    echo "[ERRO] $(date '+%Y-%m-%d %H:%M:%S') - $mensagem" >&2
}

trap 'log_erro "Script interrompido inesperadamente"' ERR

if [[ $# -lt 1 ]]; then
    echo "Uso: $0 <diretorio>" >&2
    exit 1
fi

O comando set -e faz o script parar ao primeiro erro, set -u trata variáveis não definidas como erro e set -o pipefail captura falhas em pipes. O trap permite executar ações de limpeza quando o script termina abruptamente.

2. Automação de backups e sincronização de arquivos

Backups manuais são propensos a esquecimento. Um script automatizado com rsync pode fazer backup incremental, copiando apenas arquivos modificados. A compactação com tar reduz o espaço ocupado, e a rotação de backups antigos evita acumular arquivos desnecessários.

#!/bin/bash
ORIGEM="/home/usuario/documentos"
DESTINO="/mnt/backup/documentos"
LOG="/var/log/backup.log"
RETENCAO=7

executar_backup() {
    local data=$(date +%Y%m%d_%H%M%S)
    local arquivo="backup_${data}.tar.gz"

    rsync -avz --delete "$ORIGEM" "$DESTINO/atual" >> "$LOG" 2>&1
    tar -czf "$DESTINO/historico/$arquivo" -C "$DESTINO" atual

    find "$DESTINO/historico" -name "*.tar.gz" -mtime +$RETENCAO -delete
    echo "$(date) - Backup concluído: $arquivo" >> "$LOG"
}

executar_backup

Para sincronização remota via SSH, basta adicionar -e "ssh -p 2222" ao rsync e configurar chaves SSH para acesso sem senha.

3. Gerenciamento de logs e monitoramento do sistema

Logs crescem rapidamente e podem ocupar espaço em disco. Um script de rotação remove arquivos antigos e mantém apenas os recentes. Combinado com cron, a limpeza ocorre automaticamente.

#!/bin/bash
DIR_LOG="/var/log/meuapp"
DIAS_RETER=30
ALERTA_USO=80

limpar_logs() {
    find "$DIR_LOG" -name "*.log" -mtime +$DIAS_RETER -delete
    find "$DIR_LOG" -name "*.log.*" -mtime +$DIAS_RETER -delete
    echo "$(date) - Logs antigos removidos" >> /var/log/limpeza.log
}

monitorar_disco() {
    local uso=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
    if [[ $uso -gt $ALERTA_USO ]]; then
        echo "ALERTA: Disco com ${uso}% de uso" | mail -s "Alerta de disco" admin@exemplo.com
    fi
}

coletar_metricas() {
    local cpu=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')
    local memoria=$(free -m | awk 'NR==2 {print $3}')
    local data=$(date '+%Y-%m-%d %H:%M:%S')
    echo "$data,$cpu,$memoria" >> /var/log/metricas.csv
}

limpar_logs
monitorar_disco
coletar_metricas

4. Manipulação de arquivos e processamento de texto

Renomear dezenas de arquivos manualmente é tedioso. Com sed e rename, é possível aplicar transformações em lote. O awk é poderoso para extrair colunas de logs e o grep para filtrar linhas específicas.

#!/bin/bash
# Renomeia arquivos .jpg substituindo espaços por underscores
for arquivo in *.jpg; do
    novo_nome=$(echo "$arquivo" | sed 's/ /_/g' | tr '[:upper:]' '[:lower:]')
    mv "$arquivo" "$novo_nome"
done

# Extrai endereços IP de um arquivo de log
grep -oP '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' /var/log/access.log | sort -u

# Remove linhas duplicadas de um CSV baseado na primeira coluna
awk -F',' '!seen[$1]++' dados.csv > dados_unicos.csv

Para CSV mal formatado com quebras de linha no meio dos campos, use awk com um estado para rastrear se está dentro de aspas.

5. Automação de tarefas de rede e conectividade

Verificar se servidores estão online e baixar arquivos condicionalmente são tarefas comuns. O ping testa conectividade básica, enquanto nc verifica portas específicas. Para downloads com retry automático, loops com curl são eficientes.

#!/bin/bash
HOSTS=("google.com" "github.com" "meuservidor.com")
ARQUIVO_URL="https://exemplo.com/arquivo.zip"
MAX_TENTATIVAS=3

verificar_hosts() {
    for host in "${HOSTS[@]}"; do
        if ping -c 1 -W 2 "$host" &>/dev/null; then
            echo "✓ $host está acessível"
        else
            echo "✗ $host não respondeu"
        fi
    done
}

baixar_com_retry() {
    local tentativa=0
    while [[ $tentativa -lt $MAX_TENTATIVAS ]]; do
        if curl -L -f -o "arquivo.zip" "$ARQUIVO_URL"; then
            echo "Download concluído"
            return 0
        fi
        ((tentativa++))
        sleep 5
    done
    echo "Falha após $MAX_TENTATIVAS tentativas" >&2
    return 1
}

verificar_hosts
baixar_com_retry

6. Scripts para produtividade no terminal

Aliases e funções no .bashrc economizam digitação. Um script para criar projetos com estrutura padrão acelera o início de novos trabalhos. A busca e substituição interativa permite modificar múltiplos arquivos com segurança.

# No .bashrc
alias ll='ls -lah'
alias gp='git push origin $(git branch --show-current)'

criar_projeto() {
    local nome="$1"
    mkdir -p "$nome"/{src,docs,tests}
    touch "$nome/README.md"
    touch "$nome/src/main.sh"
    echo "#!/bin/bash" > "$nome/src/main.sh"
    chmod +x "$nome/src/main.sh"
    echo "Projeto $nome criado em $(pwd)/$nome"
}

buscar_substituir() {
    local padrao="$1"
    local substituicao="$2"
    local arquivos=$(grep -rl "$padrao" . --include="*.sh" --include="*.txt")
    for arquivo in $arquivos; do
        sed -i "s/$padrao/$substituicao/g" "$arquivo"
        echo "Modificado: $arquivo"
    done
}

7. Integração com APIs e serviços web

Consultar APIs REST e processar JSON com jq permite automatizar coleta de dados. Notificações para Slack ou Telegram mantêm a equipe informada. Upload para serviços cloud como S3 pode ser feito com aws-cli encapsulado em script.

#!/bin/bash
API_URL="https://api.github.com/repos/usuario/repo"
SLACK_WEBHOOK="https://hooks.slack.com/services/TOKEN"

consultar_api() {
    curl -s "$API_URL" | jq '{nome: .name, estrelas: .stargazers_count, forks: .forks_count}'
}

enviar_notificacao() {
    local mensagem="$1"
    curl -s -X POST -H 'Content-type: application/json' \
        --data "{\"text\":\"$mensagem\"}" "$SLACK_WEBHOOK"
}

upload_cloud() {
    local arquivo="$1"
    aws s3 cp "$arquivo" s3://meu-bucket/backups/
    echo "Upload concluído: $arquivo"
}

dados=$(consultar_api)
enviar_notificacao "Repositório atualizado: $dados"

8. Boas práticas, testes e documentação

O shellcheck analisa scripts e aponta erros comuns como variáveis sem aspas ou comandos inseguros. Testes com bats permitem verificar o comportamento esperado. Documentação clara com cabeçalho, opção --help e exemplos facilita o uso por outras pessoas.

#!/bin/bash
# Script: organizar_arquivos.sh
# Descrição: Organiza arquivos em pastas por extensão
# Uso: ./organizar_arquivos.sh [diretorio]
# Exemplo: ./organizar_arquivos.sh ~/Downloads

# Instalar shellcheck: sudo apt install shellcheck
# shellcheck disable=SC2086

mostrar_ajuda() {
    cat << EOF
Uso: $0 [OPÇÕES] [diretorio]
Organiza arquivos em subpastas baseado na extensão.

Opções:
  -h, --help    Mostra esta ajuda
  -d, --dry-run Simula a organização sem mover arquivos

Exemplos:
  $0 ~/Downloads
  $0 --dry-run ~/Documentos
EOF
}

if [[ "$1" == "-h" || "$1" == "--help" ]]; then
    mostrar_ajuda
    exit 0
fi

Para testar com bats, crie arquivos .bats com funções de teste que verificam saídas e códigos de retorno.

Referências

  • GNU Bash Manual — Documentação oficial do Bash com todas as funcionalidades da linguagem
  • ShellCheck - Shell Script Analysis Tool — Ferramenta online e CLI para encontrar erros e vulnerabilidades em scripts Shell
  • Advanced Bash-Scripting Guide — Guia avançado e completo sobre programação em Bash, com centenas de exemplos práticos
  • Bats: Bash Automated Testing System — Framework de testes unitários para scripts Bash, com integração contínua
  • rsync man page — Documentação completa do rsync para backup e sincronização eficiente de arquivos
  • jq Manual — Guia de referência do jq, processador de JSON essencial para scripts que interagem com APIs
  • Cron How-To — Tutorial prático sobre agendamento de tarefas com cron para automação de scripts