Resolvendo Erros Comuns de Sintaxe no Bash: Um Guia Prático
Corrija erros comuns de sintaxe no Bash com exemplos para aspas, colchetes, variáveis, redirecionamentos e problemas de localização de comandos.
Resolvendo Erros Comuns de Sintaxe no Bash: Um Guia Prático
Erros de sintaxe no Bash geralmente vêm de pequenos enganos: uma aspa faltando, um colchete errado, um redirecionamento mal colocado ou uma variável que se expandiu para algo inesperado. Quando seu script Bash parar com syntax error near unexpected token, comece verificando a linha anterior à que o Bash reporta, depois execute o script com uma verificação de sintaxe.
Use esta verificação rápida antes de executar um script modificado em um servidor:
bash -n script.sh
bash -n analisa o arquivo sem executar comandos. Não vai pegar todos os bugs lógicos, mas pega muitas aspas quebradas, declarações fi faltando e loops malformados.
Aspas Faltando
Aspas não fechadas são uma das maneiras mais rápidas de confundir o analisador.
nome="deploy
printf 'Implantando %s\n' "$nome"
O Bash continua lendo linhas subsequentes porque ainda está procurando o " de fechamento. Corrija fechando a aspa e colocando entre aspas as expansões de variáveis que podem conter espaços:
nome="deploy"
printf 'Implantando %s\n' "$nome"
Use aspas duplas quando quiser que variáveis se expandam. Use aspas simples quando quiser texto literal:
printf 'HOME permanece literal: $HOME\n'
printf "HOME expande: %s\n" "$HOME"
Blocos if, for e while Incorretos
Todo comando composto precisa de sua palavra-chave de fechamento. A falta de uma geralmente reporta o erro perto do final do arquivo.
if systemctl is-active --quiet nginx; then
echo "nginx está rodando"
# faltando fi
Versão correta:
if systemctl is-active --quiet nginx; then
echo "nginx está rodando"
fi
O mesmo padrão se aplica a loops e declarações case:
for host in web1 web2 web3; do
ssh "$host" uptime
done
case "$env" in
prod) echo "produção" ;;
dev) echo "desenvolvimento" ;;
*) echo "desconhecido" ;;
esac
Erros com Colchetes e Testes
O comando [ é um comando real, então precisa de espaços ao redor de seus argumentos e antes do colchete de fechamento.
Quebrado:
if [$count -gt 5]; then
echo "muitos"
fi
Corrigido:
if [ "$count" -gt 5 ]; then
echo "muitos"
fi
Para scripts específicos do Bash, [[ ... ]] é geralmente mais seguro para testes de string porque lida com variáveis vazias de forma mais elegante e suporta correspondência de padrões:
if [[ "$file" == *.log ]]; then
gzip "$file"
fi
Use operadores numéricos para números e operadores de string para texto:
[[ "$status" == "pronto" ]] # comparação de string
[[ "$retries" -lt 3 ]] # comparação numérica
Problemas com Expansão de Variáveis
Um erro comum é adicionar espaços ao redor de = durante a atribuição. O Bash trata isso como um comando em vez de uma atribuição de variável.
Quebrado:
backup_dir = /var/backups
Corrigido:
backup_dir=/var/backups
Use chaves quando o nome da variável tocar em outro texto:
servico="nginx"
log="/var/log/${servico}.log"
Sem chaves, o Bash pode ler um nome de variável mais longo do que você pretendia.
Erros de comando não encontrado
comando não encontrado nem sempre é um erro de sintaxe. Geralmente significa que o Bash não conseguiu encontrar um executável com esse nome.
Verifique primeiro se há erros de digitação:
systemctl status nginx
Depois verifique se o comando existe e está no PATH:
command -v systemctl
printf '%s\n' "$PATH"
Se o script rodar sob cron, systemd ou um job de CI, o PATH pode ser mais curto que o do seu shell interativo. Use caminhos absolutos para comandos críticos ou defina PATH perto do topo do script:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
Erros de Redirecionamento e Pipe
A ordem do redirecionamento importa. Este comando escreve a saída padrão em app.log e depois envia a saída de erro para o mesmo lugar:
./deploy.sh >app.log 2>&1
Este é diferente porque a saída de erro é copiada para a saída padrão antiga antes que a saída padrão seja redirecionada:
./deploy.sh 2>&1 >app.log
Para pipelines, lembre-se de que o Bash normalmente retorna o código de saída do último comando. Use pipefail quando um comando falho no meio deve falhar todo o pipeline:
set -o pipefail
kubectl get pods | grep CrashLoopBackOff
Um Fluxo de Depuração Prático
Comece com uma verificação de sintaxe:
bash -n script.sh
Execute com rastreamento quando a sintaxe for válida, mas o comportamento estiver errado:
bash -x script.sh
Para scripts de produção mais seguros, adicione modo estrito deliberadamente e teste o script após cada alteração:
set -euo pipefail
set -e sai em muitas falhas de comando, set -u trata variáveis não definidas como erros e pipefail captura falhas dentro de pipelines. Essas opções são úteis, mas podem alterar o comportamento do script, então habilite-as intencionalmente em vez de colocá-las em um script antigo sem testar.
Conclusão
A maioria dos erros de sintaxe do Bash se torna simples quando você verifica aspas, palavras-chave de fechamento, espaçamento de colchetes, atribuições de variáveis e redirecionamentos nessa ordem. Mantenha bash -n e bash -x no seu fluxo de trabalho normal e teste scripts com o mesmo shell e ambiente que serão usados em produção.