Depurando scripts
Esta aula aborda técnicas essenciais para depuração de scripts Bash, incluindo o uso de bash -x, set -x/set +x, logging e a ferramenta ShellCheck. O objetivo é capacitar o aluno a identificar e corrigir erros de forma eficiente.
Depurar scripts é uma habilidade fundamental para qualquer desenvolvedor que trabalhe com shell script. Erros de sintaxe, lógica ou variáveis não definidas podem causar comportamentos inesperados. Nesta aula, você aprenderá técnicas práticas para rastrear a execução do seu código, entender o que está acontecendo em cada etapa e encontrar bugs mais rapidamente.
Vamos explorar desde a execução com rastreamento (bash -x) até o uso de pontos de ativação/desativação do modo debug (set -x e set +x), logging personalizado e a ferramenta estática ShellCheck, que analisa seu código sem executá-lo.
bash -x
O modo mais simples e direto de depurar um script é executá-lo com a opção -x do Bash. Isso faz com que cada comando seja exibido no terminal antes de ser executado, precedido por um sinal de mais (+). As expansões de variáveis e substituições são mostradas, permitindo visualizar os valores reais sendo usados.
Por exemplo, considere o script soma.sh:
#!/bin/bash
a=10
b=20
soma=$((a + b))
echo "A soma é $soma"Ao executar bash -x soma.sh, a saída será algo como:
+ a=10
+ b=20
+ soma=30
+ echo 'A soma é 30'
A soma é 30Isso mostra exatamente o que o interpretador está fazendo. Se houver um erro, como uma variável não definida, o rastreamento ajuda a identificar onde o problema ocorre.
set -x e set +x
Em vez de depurar o script inteiro, você pode ativar e desativar o rastreamento em partes específicas usando set -x (ativar) e set +x (desativar). Isso é útil quando você quer focar apenas em uma seção problemática sem o ruído de todo o script.
Exemplo:
#!/bin/bash
echo "Início do script"
set -x
a=10
b=20
soma=$((a + b))
echo "Soma: $soma"
set +x
echo "Fim do script"A saída será:
Início do script
+ a=10
+ b=20
+ soma=30
+ echo 'Soma: 30'
Soma: 30
Fim do scriptNote que apenas os comandos entre set -x e set +x são rastreados. Você também pode usar set -v para exibir as linhas de entrada (antes da expansão) e set -xv para combinar ambos.
Logging
Adicionar mensagens de log ao seu script é uma prática essencial para depuração e manutenção. Em vez de depender apenas do rastreamento, você pode inserir instruções echo ou usar uma função de logging que exiba timestamps, níveis de severidade e informações contextuais.
Exemplo de função de logging simples:
#!/bin/bash
log() {
local level="$1"
local msg="$2"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $msg"
}
log "INFO" "Iniciando script"
a=10
log "DEBUG" "a = $a"
b=20
log "DEBUG" "b = $b"
soma=$((a + b))
log "INFO" "Soma calculada: $soma"
echo "Resultado: $soma"
log "INFO" "Script finalizado"Você pode redirecionar a saída de log para um arquivo (exec >> logfile.log) ou para o stderr, e até usar níveis como DEBUG, INFO, WARN e ERROR. Isso facilita o monitoramento e a análise posterior.
shellcheck (visão geral)
ShellCheck é uma ferramenta de análise estática para scripts shell. Ela não executa o script, mas analisa o código fonte em busca de erros comuns, problemas de sintaxe, más práticas e possíveis bugs. É extremamente útil para detectar problemas antes mesmo de testar.
Para usar, instale via gerenciador de pacotes (ex.: apt install shellcheck no Ubuntu, brew install shellcheck no macOS) e execute:
shellcheck seu_script.shExemplo de saída:
In seu_script.sh line 6:
echo "A soma é $soma"
^-- SC2148: Tips depend on target shell and yours is unknown. Add shebang.
^-- SC2086: Double quote to prevent globbing and word splitting.Cada aviso tem um código (ex.: SC2086) que remete a uma página de documentação explicando o problema e como corrigi-lo. Integrar ShellCheck ao seu editor (VS Code, Vim, etc.) permite feedback em tempo real enquanto você escreve o script.
Boas práticas e observações finais
Combine as técnicas: use bash -x para uma visão geral, set -x/set +x para isolar trechos, logging para ter um histórico e ShellCheck para prevenir erros. Sempre teste scripts em um ambiente seguro antes de colocar em produção. Lembre-se de que depuração é um processo iterativo; quanto mais cedo você detectar um erro, mais fácil corrigi-lo.
Referências
- GNU Bash Manual: The Set Builtin
- ShellCheck - shell script analysis tool
- Bash man page (linux.die.net)
- Bash Beginners Guide: Debugging
- ShellCheck GitHub repository
- Baeldung: Debugging Bash Scripts
Exercícios
Considere o script abaixo. Execute-o com
bash -xe explique o que cada linha do rastreamento significa.#!/bin/bash nome="Alice" echo "Olá, $nome" idade=25 echo "Idade: $idade"✓ Resposta: A saída será algo como:
Cada linha iniciada com '+' mostra o comando após a expansão de variáveis. A linha+ nome=Alice + echo 'Olá, Alice' Olá, Alice + idade=25 + echo 'Idade: 25' Idade: 25+ nome=Aliceindica a atribuição da variável.+ echo 'Olá, Alice'mostra o comando echo com a variável já expandida. As linhas seguintes seguem o mesmo padrão.Modifique o script do exercício 1 para que apenas a parte que exibe a idade seja rastreada usando
set -xeset +x. Escreva o script modificado.✓ Resposta:
Ao executar, apenas as linhas entre#!/bin/bash nome="Alice" echo "Olá, $nome" set -x idade=25 echo "Idade: $idade" set +xset -xeset +xserão rastreadas.Crie uma função de logging que escreva mensagens com timestamp e nível (INFO, DEBUG, ERROR) em um arquivo
script.log. Use-a em um script simples que define duas variáveis e as exibe.✓ Resposta:
Execute e verifique o conteúdo de#!/bin/bash log() { local level="$1" local msg="$2" echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $msg" >> script.log } log "INFO" "Início do script" a=10 log "DEBUG" "a = $a" b=20 log "DEBUG" "b = $b" echo "a=$a, b=$b" log "INFO" "Fim do script"script.log.Execute o ShellCheck no script abaixo e liste pelo menos dois avisos que ele emitiria (não precisa corrigir).
#!/bin/bash nome="João" echo "Olá, $nome" for i in 1 2 3; do echo $i done✓ Resposta: ShellCheck provavelmente emitiria:- SC2086: Double quote to prevent globbing and word splitting (na linha
echo $i). - SC2034: 'nome' appears unused (se a variável não for usada depois).
- SC2148: Tips depend on target shell and yours is unknown. Add shebang. (já tem shebang, mas pode reclamar se não estiver na primeira linha).
- SC2086: Double quote to prevent globbing and word splitting (na linha
Escreva um script que contenha um erro proposital (ex.: variável não definida ou comando digitado errado). Use
bash -xpara encontrar o erro e descreva como o rastreamento ajudou.✓ Resposta: Exemplo de script com erro:
Ao executar com#!/bin/bash echo "Calculando..." resultado=$((10 / 0)) echo "Resultado: $resultado"bash -x, a saída mostra:
O rastreamento mostra exatamente onde a divisão por zero ocorre, indicando a linha e o erro. Isso permite corrigir rapidamente.+ echo 'Calculando...' Calculando... + resultado=10 / 0 bash: line 4: 10 / 0: division by 0 (error token is "0 ")