Debugging de scripts com set -x
1. Introdução ao set -x: O que é e para que serve
1.1. Definição: ativa o modo de rastreamento (trace mode) no Bash
O comando set -x ativa o modo de rastreamento (trace mode) no Bash. Quando ativado, o shell exibe cada comando antes de executá-lo, permitindo que o desenvolvedor acompanhe passo a passo a execução do script. Essa é uma das ferramentas mais poderosas para depuração de scripts shell.
1.2. Comportamento básico: exibe cada comando antes de executá-lo, precedido por +
Quando o modo trace está ativo, cada comando é impresso no stderr precedido pelo caractere +. Isso inclui comandos simples, estruturas de controle, expansões de variáveis e substituições de comandos.
#!/bin/bash
set -x
nome="João"
echo "Olá, $nome"
set +x
Saída esperada:
+ nome=João
+ echo 'Olá, João'
Olá, João
1.3. Diferença entre set -x e outras opções de depuração (set -v, set -n)
O Bash oferece três opções principais de depuração:
set -x: Exibe comandos após expansão (mostra valores reais das variáveis)set -v: Exibe comandos antes da expansão (mostra o código fonte literal)set -n: Apenas interpreta o script sem executar (verifica erros de sintaxe)
#!/bin/bash
# Exemplo comparativo
var="mundo"
echo "Olá, $var"
Com set -v:
echo "Olá, $var"
Olá, mundo
Com set -x:
+ echo 'Olá, mundo'
Olá, mundo
2. Ativando e desativando o modo de depuração
2.1. Uso global: set -x no início do script e set +x para desativar
Para depurar um script inteiro, coloque set -x logo após o shebang:
#!/bin/bash
set -x
# Todo o script será rastreado
contador=0
while [ $contador -lt 3 ]; do
echo "Iteração $contador"
((contador++))
done
set +x
2.2. Uso localizado: blocos específicos com set -x e set +x
Para depurar apenas seções problemáticas:
#!/bin/bash
echo "Início do script (sem debug)"
set -x # Ativa debug
for arquivo in *.txt; do
wc -l "$arquivo"
done
set +x # Desativa debug
echo "Fim do script (sem debug)"
2.3. Execução direta na linha de comando: bash -x script.sh
Sem modificar o script, execute-o com a flag -x:
bash -x meu_script.sh
Isso ativa o trace mode para toda a execução, independentemente de set -x estar presente no código.
3. Interpretando a saída do set -x
3.1. O significado do prefixo + e níveis de aninhamento (expansão de ++)
Cada nível de aninhamento adiciona um + extra. Subshells, substituições de comandos e pipes dentro de estruturas complexas geram níveis mais profundos:
#!/bin/bash
set -x
resultado=$(echo "subshell" | tr 'a-z' 'A-Z')
echo "$resultado"
Saída:
++ echo subshell
++ tr a-z A-Z
+ resultado=SUBSHELL
+ echo SUBSHELL
SUBSHELL
3.2. Visualização de variáveis expandidas: valores reais vs. nomes das variáveis
O set -x mostra o comando com as variáveis já expandidas, facilitando a identificação de valores inesperados:
#!/bin/bash
set -x
arquivo="/tmp/meu arquivo.txt"
cat $arquivo # Problema: sem aspas
cat "$arquivo" # Correto: com aspas
Saída:
+ arquivo='/tmp/meu arquivo.txt'
+ cat /tmp/meu arquivo.txt # Mostra dois argumentos separados
cat: /tmp/meu: No such file or directory
cat: arquivo.txt: No such file or directory
+ cat '/tmp/meu arquivo.txt' # Mostra um único argumento
3.3. Identificação de comandos, pipes, redirecionamentos e subshells na saída
#!/bin/bash
set -x
ls -la | grep ".txt" > arquivos.txt
(echo "subshell"; pwd)
Saída:
+ ls -la
+ grep .txt
+ ls -la
+ grep .txt
++ echo subshell
++ pwd
+ echo subshell
+ pwd
subshell
/home/usuario
4. Casos práticos de uso do set -x
4.1. Depuração de loops: verificando iterações e valores de variáveis
#!/bin/bash
set -x
soma=0
for i in {1..5}; do
((soma += i))
echo "Soma parcial: $soma"
done
echo "Soma total: $soma"
4.2. Depuração de condicionais (if, case): vendo o fluxo de decisão
#!/bin/bash
set -x
arquivo="/etc/passwd"
if [ -f "$arquivo" ] && [ -r "$arquivo" ]; then
echo "Arquivo existe e é legível"
elif [ -f "$arquivo" ]; then
echo "Arquivo existe mas não é legível"
else
echo "Arquivo não existe"
fi
4.3. Depuração de funções: rastreamento de chamadas e parâmetros
#!/bin/bash
set -x
calcular_media() {
local total=$(($1 + $2 + $3))
local media=$(echo "scale=2; $total / 3" | bc)
echo "Média: $media"
}
calcular_media 8 7 9
5. Combinando set -x com outras ferramentas de depuração
5.1. Uso conjunto com set -e (exit on error) e set -u (unset variables)
#!/bin/bash
set -eux # Combina exit on error, unset variables e trace mode
# O script para ao primeiro erro e mostra cada comando
nome="Maria"
echo "$nome"
echo "$sobrenome" # Isso causará erro (variável não definida)
5.2. Redirecionamento da saída de depuração para um arquivo: exec 2>debug.log
Para não poluir a saída padrão:
#!/bin/bash
exec 2>debug.log # Redireciona stderr (onde o set -x escreve)
set -x
echo "Processando..."
# ... resto do script
5.3. Integração com PS4 para personalizar o prompt de depuração
A variável PS4 controla o prefixo exibido pelo set -x:
#!/bin/bash
export PS4='+ [LINHA $LINENO] ' # Mostra o número da linha
set -x
nome="Ana"
echo "Olá, $nome"
Saída:
+ [LINHA 5] nome=Ana
+ [LINHA 6] echo 'Olá, Ana'
Olá, Ana
6. Boas práticas e armadilhas comuns
6.1. Cuidado com informações sensíveis: senhas e tokens em variáveis
#!/bin/bash
set -x
senha="minha_senha_secreta_123" # ISSO SERÁ EXIBIDO NO LOG!
echo "Autenticando..."
Solução: Desative set -x antes de manipular dados sensíveis.
6.2. Impacto na performance: evitar set -x em scripts de produção
O set -x adiciona overhead significativo. Use apenas durante desenvolvimento e depuração.
6.3. Desativação segura: uso de trap para desligar set -x em caso de erro
#!/bin/bash
set -x
trap 'set +x; echo "Debug desativado após erro"' ERR
# Código que pode falhar
comando_inexistente
echo "Isso não será executado"
7. Alternativas e complementos ao set -x
7.1. Uso de bash -x vs. set -x dentro do script
bash -x script.sh: Ideal para depuração única, sem modificar o scriptset -xno script: Útil para depuração contínua ou seletiva
7.2. Depuração com trap 'echo "Erro na linha $LINENO"' ERR para pontos específicos
#!/bin/bash
trap 'echo "ERRO na linha $LINENO: comando falhou"' ERR
comando1
comando_inexistente # Isso dispara o trap
comando2
7.3. Ferramentas externas: shellcheck para análise estática combinada com set -x
# Instalação (Linux)
sudo apt install shellcheck
# Uso
shellcheck meu_script.sh
O ShellCheck identifica problemas comuns que o set -x ajuda a confirmar durante a execução.
8. Exemplo completo: depurando um script real
8.1. Script com bug (loop infinito)
#!/bin/bash
# Script para processar arquivos de log
contador=0
total_linhas=0
while [ $contador -lt 5 ]; do
for arquivo in *.log; do
linhas=$(wc -l < "$arquivo")
total_linhas=$((total_linhas + linhas))
echo "Processado: $arquivo ($linhas linhas)"
done
# BUG: contador nunca é incrementado!
done
echo "Total de linhas: $total_linhas"
8.2. Aplicação passo a passo do set -x para identificar o problema
#!/bin/bash
set -x # Ativa debug
contador=0
total_linhas=0
while [ $contador -lt 5 ]; do
for arquivo in *.log; do
linhas=$(wc -l < "$arquivo")
total_linhas=$((total_linhas + linhas))
echo "Processado: $arquivo ($linhas linhas)"
done
# Observamos que contador nunca muda
done
set +x
echo "Total de linhas: $total_linhas"
Ao executar com set -x, vemos claramente que o valor de contador permanece 0 em todas as iterações.
8.3. Correção do script e verificação com set -x desativado
#!/bin/bash
contador=0
total_linhas=0
while [ $contador -lt 5 ]; do
for arquivo in *.log; do
linhas=$(wc -l < "$arquivo")
total_linhas=$((total_linhas + linhas))
echo "Processado: $arquivo ($linhas linhas)"
done
((contador++)) # CORREÇÃO: incrementa o contador
done
echo "Total de linhas: $total_linhas"
Após a correção, podemos remover o set -x ou mantê-lo apenas para verificar se a solução funciona corretamente.
Referências
-
GNU Bash Manual: The Set Builtin — Documentação oficial do Bash sobre o comando
set, incluindo a opção-xpara trace mode. -
Bash Debugging with set -x (Linuxize) — Tutorial completo sobre depuração de scripts Bash, com foco em
set -x,set -eeset -u. -
ShellCheck - Static Analysis Tool for Shell Scripts — Ferramenta online e CLI para análise estática de scripts shell, complementar ao
set -x. -
Advanced Bash-Scripting Guide: Debugging — Guia avançado do The Linux Documentation Project sobre técnicas de depuração em Bash, incluindo
set -x,trapePS4. -
Bash Debugging Techniques (Red Hat Developer) — Artigo técnico da Red Hat cobrindo
set -x,bash -x,PS4personalizado e boas práticas de depuração. -
Using PS4 to Enhance Bash Debugging (How-To Geek) — Guia prático sobre como personalizar o prompt de depuração com a variável
PS4para obter informações mais detalhadas.