Shell scripting para automação
Esta aula ensina shell scripting para automação de tarefas em DevOps, cobrindo scripts úteis, variáveis de ambiente, cron e quando usar shell vs ferramentas dedicadas. Inclui exemplos práticos, boas práticas e exercícios com respostas.
Shell scripting é uma habilidade fundamental para DevOps, permitindo automatizar tarefas repetitivas como backups, deploy, monitoramento e configuração de servidores. Nesta aula, você aprenderá a criar scripts robustos, gerenciar variáveis de ambiente, agendar tarefas com cron e decidir quando usar shell ou ferramentas especializadas.
Dominar shell scripting aumenta sua produtividade e confiabilidade, já que scripts podem ser versionados, testados e reutilizados. Vamos explorar desde exemplos práticos até boas práticas de segurança e manutenção.
Scripts úteis
Scripts shell podem automatizar tarefas comuns do dia a dia, como backup de diretórios, monitoramento de logs, deploy de aplicações e limpeza de arquivos temporários. Eles são especialmente úteis em ambientes Unix/Linux, onde o shell é onipresente.
Exemplo: script de backup compactado com timestamp.
#!/bin/bash
# backup.sh - Backup de diretório com timestamp
BACKUP_DIR="/backups"
SOURCE_DIR="/var/www/html"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
FILENAME="backup_${TIMESTAMP}.tar.gz"
echo "Iniciando backup de $SOURCE_DIR para $BACKUP_DIR/$FILENAME..."
tar -czf "$BACKUP_DIR/$FILENAME" "$SOURCE_DIR"
echo "Backup concluído: $BACKUP_DIR/$FILENAME"
Outro script útil é o monitor de espaço em disco, que envia alerta se a utilização exceder um limiar.
#!/bin/bash
# disk_monitor.sh - Alerta se uso de disco > 80%
THRESHOLD=80
USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "ALERTA: Uso de disco em / é ${USAGE}% (limite: ${THRESHOLD}%)" | mail -s "Alerta de Disco" admin@exemplo.com
fi
Variáveis de ambiente
Variáveis de ambiente são valores dinâmicos que influenciam o comportamento de processos no sistema. No shell, são acessadas com o prefixo $ e podem ser definidas no terminal ou em scripts. Exemplos comuns: PATH, HOME, USER. Para definir uma variável no script: VAR=valor (sem espaços). Para exportar para subprocessos: export VAR.
Boas práticas: use nomes em maiúsculas para variáveis de ambiente, evite sobrescrever variáveis do sistema, e utilize ${} para evitar ambiguidades. Exemplo de script que verifica se uma variável está definida:
#!/bin/bash
if [ -z "$DEPLOY_KEY" ]; then
echo "Erro: DEPLOY_KEY não definida. Abortando."
exit 1
fi
echo "Chave de deploy encontrada: ${DEPLOY_KEY:0:8}..."
Para listar todas as variáveis de ambiente, use env ou printenv. Variáveis podem ser passadas na execução de um comando: VAR=valor comando.
cron
O cron é um agendador de tarefas do Unix que executa scripts em intervalos definidos. A configuração é feita no arquivo crontab (acessado com crontab -e). Cada linha segue o formato: minuto hora dia mês semana comando.
Exemplos de agendamento:
0 2 * * * /scripts/backup.sh– Executa diariamente às 2h.*/10 * * * * /scripts/disk_monitor.sh– A cada 10 minutos.0 0 1 * * /scripts/monthly_report.sh– Primeiro dia de cada mês à meia-noite.
Boas práticas: sempre usar caminhos absolutos, redirecionar saída para log (> /var/log/meu_script.log 2>&1), e testar o script manualmente antes de agendar. Cuidado com variáveis de ambiente: o cron executa com um ambiente mínimo; defina variáveis no próprio script ou no crontab.
Para listar tarefas do usuário: crontab -l. Para remover: crontab -r.
Quando usar shell vs ferramenta dedicada
Shell scripting é ideal para tarefas simples, rápidas e que envolvem comandos do sistema, como manipulação de arquivos, chamadas a APIs via curl, e integração com ferramentas CLI. No entanto, para tarefas complexas, como orquestração de vários serviços, deploy em múltiplos servidores, ou processamento de dados estruturados, ferramentas dedicadas são mais adequadas.
Exemplos de ferramentas: Ansible (automação de configuração), Terraform (infraestrutura como código), Jenkins (CI/CD), Python (scripts mais complexos). Use shell quando a tarefa for linear e depender de comandos Unix; use ferramentas dedicadas quando precisar de idempotência, paralelismo, ou gerenciamento de estado.
Regra prática: se seu script ultrapassar 50 linhas ou usar muitos if/else aninhados, considere migrar para Python ou uma ferramenta específica. Shell é frágil para lógica complexa e difícil de depurar.
Boas práticas
- Use
set -epara abortar em caso de erro,set -upara variáveis não definidas, eset -o pipefailpara capturar falhas em pipes. - Valide entradas e saídas; nunca confie em dados externos.
- Adicione cabeçalho com descrição e autor.
- Utilize funções para modularizar código.
- Mantenha scripts versionados em Git.
Referências
- GNU Bash Manual
- Bash man page
- crontab man page
- ShellCheck - Static analysis for shell scripts
- Google Shell Style Guide
- Advanced Bash-Scripting Guide
Exercícios
- Crie um script que faça backup de um diretório, compactando-o com tar e nomeando o arquivo com a data atual (YYYY-MM-DD). O script deve aceitar o diretório de origem como argumento.
- Escreva um script que verifique se uma variável de ambiente chamada DATABASE_URL está definida. Se não estiver, defina um valor padrão e exiba um aviso. Em seguida, exiba o valor final.
- Agende um script de limpeza de logs (/scripts/clean_logs.sh) para executar todos os dias às 3h da manhã. Escreva a linha do crontab.
- Explique em 2-3 frases quando você deve evitar usar shell script e preferir uma ferramenta como Ansible ou Python.
- Escreva um script que liste todos os arquivos .log em /var/log que foram modificados nos últimos 7 dias e os compacte em um arquivo logs_old.tar.gz.
#!/bin/bash
if [ -z "$1" ]; then
echo "Uso: $0 diretorio_origem"
exit 1
fi
SOURCE="$1"
DATE=$(date +"%Y-%m-%d")
FILENAME="backup_${DATE}.tar.gz"
tar -czf "$FILENAME" "$SOURCE"
echo "Backup criado: $FILENAME"
#!/bin/bash
if [ -z "${DATABASE_URL+x}" ]; then
echo "AVISO: DATABASE_URL não definida. Usando valor padrão."
DATABASE_URL="postgres://localhost:5432/mydb"
fi
echo "DATABASE_URL=$DATABASE_URL"
0 3 * * * /scripts/clean_logs.sh
#!/bin/bash
find /var/log -name "*.log" -mtime -7 -type f -print0 | xargs -0 tar -czf logs_old.tar.gz
echo "Arquivos compactados em logs_old.tar.gz"