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