Scripts shell frequentemente começam como três comandos colados em um arquivo. Depois ganham argumentos, verificações de ambiente, limpeza e responsabilidades de produção. Nesse ponto, estrutura deixa de ser estética: ela determina se o script falha de forma previsível e pode ser mantido com segurança.
O Bash não possui a convenção __main__ do Python, mas a ideia é útil: defina funções pequenas, mantenha a inicialização explícita e chame uma única função main ao final.
#!/usr/bin/env bash
set -Eeuo pipefail
usage() {
printf 'Uso: %s --environment <nome>\n' "${0##*/}"
}
cleanup() {
local exit_code=$?
# Libere recursos temporários aqui.
exit "$exit_code"
}
main() {
local environment=""
while (($#)); do
case "$1" in
--environment)
[[ $# -ge 2 ]] || { usage >&2; return 2; }
environment=$2
shift 2
;;
-h|--help)
usage
return 0
;;
*)
printf 'Argumento desconhecido: %s\n' "$1" >&2
usage >&2
return 2
;;
esac
done
[[ -n "$environment" ]] || { usage >&2; return 2; }
printf 'Executando para o ambiente: %s\n' "$environment"
}
trap cleanup EXIT
main "$@"
O que essa estrutura oferece
main "$@" preserva os argumentos originais e deixa o ponto de entrada visível. Funções podem ser lidas e testadas isoladamente, enquanto a sequência de execução permanece em um único lugar.
set -Eeuo pipefail ajuda a revelar falhas, mas não substitui tratamento intencional. Comandos usados em condições possuem semântica própria, variáveis podem ser opcionalmente vazias e cleanup precisa preservar o código de saída original. Entenda cada opção antes de adotá-la.
Valide antes de modificar
Analise argumentos e valide pré-condições antes de mudar estado. Confirme executáveis, arquivos, permissões e contexto de ambiente. Use caminhos explícitos e coloque variáveis entre aspas. Não reutilize nomes como HOME para opções da aplicação.
Para temporários, use mktemp -d e um trap de limpeza. Para infraestrutura ou dados, ofereça dry-run e torne execuções repetidas idempotentes quando possível.
Se portabilidade POSIX for necessária, não use sintaxe exclusiva de Bash em um script identificado como sh. Se Bash for dependência, declare isso no shebang e documente a faixa suportada.
Adicione verificações automatizadas
Execute ShellCheck no CI, mantenha formatação consistente e teste caminhos importantes. Bats pode exercitar funções, mas uma suite pequena cobrindo argumentos inválidos, dependências ausentes, cleanup e códigos de saída já aumenta muito a confiança.
Também existe um limite: quando o script exige estruturas complexas, muita concorrência ou um grande grafo de dependências, uma linguagem de propósito geral pode ser mais fácil de testar e operar.
Uma função main não torna o script pronto para produção sozinha. Ela cria uma entrada clara para validação, erros, observabilidade e testes — as práticas que realmente tornam a automação confiável.
Referências
O manual do GNU Bash é a referência da linguagem, enquanto o ShellCheck oferece análise estática para defeitos comuns em shell.
