Análise de opções e argumentos com getopts
Implemente interfaces de linha de comando profissionais usando getopts para opções curtas, argumentos obrigatórios e mensagens de uso.
Análise de opções e argumentos com getopts é uma aula grátis de DevOps Bootcamp no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de DevOps Bootcamp, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de DevOps Bootcamp inclui 4 aulas no total.
Por que getopts existe
Todo script do mundo real acaba precisando aceitar opções como -v, -o output.txt ou -n 5. Analisá-las manualmente com $1, $2… rapidamente se torna frágil.
getopts é o comando integrado padronizado pelo POSIX que lida de modo confiável com opções curtas (-a, -b), inclusive opções que recebem um argumento. Ele está integrado a todo shell POSIX, portanto não são necessárias dependências.
- Lida com sinalizadores combinados:
-vn 5=-v -n 5 - Relata opções desconhecidas de maneira adequada
- Define automaticamente as variáveis padrão
OPTINDeOPTARG
Nesta lição, você criará do zero uma CLI completa e profissional usando getopts.
A sintaxe de getopts
A sintaxe central é um laço while que chama getopts a cada iteração:
while getopts "optstring" varname; do
case "$varname" in
...
esac
done- optstring — uma cadeia que lista cada letra de opção aceita. Dois-pontos após uma letra significa que essa opção exige um argumento.
- varname — recebe a letra da opção atual a cada iteração.
- OPTARG — é definido automaticamente com o valor do argumento quando há dois-pontos após a letra.
- OPTIND — índice do próximo argumento a processar; use
shift $((OPTIND - 1))após o laço para expor os parâmetros posicionais restantes.
#!/usr/bin/env bash
# Minimal skeleton — shows the loop structure
while getopts 'vn:' opt; do
case "$opt" in
v) echo "Verbose mode on" ;;
n) echo "Count = $OPTARG" ;;
?) echo "Unknown option: -$OPTARG" >&2; exit 1 ;;
esac
doneDefinindo uma cadeia de opções
A cadeia de opções é uma declaração compacta do contrato da sua CLI. Cada caractere representa um sinalizador aceito.
'abc'— aceita-a,-b,-c(sem argumentos)'a:bc'—-aexige um argumento;-be-cnão exigem':abc'— os dois-pontos iniciais ativam o modo silencioso de erro (seu script trata as opções inválidas em vez de o shell exibir uma mensagem)
O modo silencioso é preferível em scripts de produção porque dá a você controle total sobre as mensagens de erro e os códigos de saída.
#!/usr/bin/env bash
# optstring ':o:vq'
# -o requires an argument (output file)
# -v verbose flag (no argument)
# -q quiet flag (no argument)
# Leading ':' = silent error mode
while getopts ':o:vq' opt; do
case "$opt" in
o) OUTPUT="$OPTARG" ;;
v) VERBOSE=1 ;;
q) QUIET=1 ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
echo "OUTPUT=$OUTPUT VERBOSE=$VERBOSE QUIET=$QUIET"OPTARG e argumentos obrigatórios
Quando uma opção é seguida por dois-pontos na cadeia de opções, getopts armazena seu valor em OPTARG. O usuário pode escrever o argumento com ou sem um espaço:
-o report.txt-oreport.txt
As duas formas são analisadas de maneira idêntica. Essa é uma das principais vantagens em relação à análise manual com $1/shift.
No modo silencioso (com ':' no início da cadeia de opções), um argumento ausente faz getopts definir varname como : e OPTARG como a letra da opção — perfeito para uma mensagem de erro específica.
#!/usr/bin/env bash
# Demonstrate OPTARG with a file-processing script
while getopts ':i:o:' opt; do
case "$opt" in
i) INPUT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
:) echo "Error: option -$OPTARG needs a value" >&2; exit 1 ;;
\?) echo "Error: unknown flag -$OPTARG" >&2; exit 1 ;;
esac
done
echo "Input : ${INPUT:-<not set>}"
echo "Output : ${OUTPUT:-<not set>}"Avançando além das opções com OPTIND
Depois que getopts termina, OPTIND contém o índice do primeiro argumento que não é uma opção. Use shift para remover todas as opções processadas, fazendo com que $1, $2… se refiram aos parâmetros posicionais restantes (por exemplo, nomes de arquivos).
A forma consagrada é sempre:
shift $((OPTIND - 1))Depois do deslocamento, $@ contém apenas os argumentos que não eram sinalizadores — os operandos do seu comando.
#!/usr/bin/env bash
# Shows OPTIND shift and leftover positional args
VERBOSE=0
while getopts ':vn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "VERBOSE=$VERBOSE COUNT=${COUNT:-1}"
echo "Remaining args: $*"Escrevendo uma função de uso
Um script profissional sempre fornece uma função usage() que exibe uma mensagem de ajuda e encerra a execução. A convenção é:
- Imprimir em stderr (descritor de arquivo 2), para não poluir a saída encaminhada por uma tubulação
- Encerrar com o código 0 para
-h/--helpe com o código 1 para uso inválido - Chamar
usage 1nos caminhos de erro eusage 0no manipulador de-h
#!/usr/bin/env bash
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-n COUNT] [-o FILE] [FILE...]
Options:
-v Verbose output
-n COUNT Repeat COUNT times (default: 1)
-o FILE Write output to FILE
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTFILE="$OPTARG" ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
echo "Parsed OK — verbose=${VERBOSE:-0} count=${COUNT:-1} out=${OUTFILE:--}"Valores padrão e validação
Depois da análise, valide os dados e defina os valores padrão antes de realizar qualquer trabalho de fato. Mantenha a fase de análise (o laço) separada da fase de lógica. Isso facilita a leitura e o teste de ambas as seções.
- Use
${VAR:-default}para valores padrão embutidos - Valide argumentos numéricos com uma expressão regular ou uma verificação aritmética
- Valide se as opções obrigatórias foram realmente fornecidas
#!/usr/bin/env bash
usage() { echo "Usage: $(basename "$0") -n COUNT [-v]" >&2; exit 1; }
VERBOSE=0
COUNT=''
while getopts ':n:v' opt; do
case "$opt" in
n) COUNT="$OPTARG" ;;
v) VERBOSE=1 ;;
:) echo "Error: -$OPTARG needs a value" >&2; usage ;;
\?) echo "Error: -$OPTARG unknown" >&2; usage ;;
esac
done
shift $((OPTIND - 1))
# Validation phase
[[ -z "$COUNT" ]] && { echo "Error: -n COUNT is required" >&2; usage; }
[[ "$COUNT" =~ ^[0-9]+$ ]] || { echo "Error: COUNT must be a positive integer" >&2; usage; }
for (( i=1; i<=COUNT; i++ )); do
[[ $VERBOSE -eq 1 ]] && echo "Iteration $i of $COUNT"
echo "Hello, world!"
doneCombinando sinalizadores na linha de comando
getopts lida automaticamente com sinalizadores curtos combinados escritos sem espaços, seguindo a convenção padrão do Unix:
-v -qequivale a-vq-n 5 -vequivale a-n5 -vou-vn5
Você não precisa escrever código adicional para aceitar isso — getopts percorre automaticamente cada caractere de uma cadeia de opções combinadas. Esse é outro motivo importante para usar getopts em vez da análise manual.
#!/usr/bin/env bash
# Test combined flag parsing
# Run as: bash script.sh -vq -n3
VERBOSE=0; QUIET=0; COUNT=1
while getopts ':vqn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
q) QUIET=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG needs value" >&2; exit 1 ;;
\?) echo "Error: unknown -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "verbose=$VERBOSE quiet=$QUIET count=$COUNT"Lidando com o separador de dois traços
Os comandos Unix aceitam -- (dois traços) como um sinal explícito para interromper o processamento de opções. Tudo depois de -- é tratado como um argumento posicional, mesmo que pareça um sinalizador.
getopts para automaticamente ao encontrar --. Depois de shift $((OPTIND - 1)), os dois traços desaparecem e $@ contém apenas os operandos.
Isso é importante para scripts que operam em nomes de arquivos que podem começar com um traço, por exemplo:
myscript.sh -v -- -strangefile.txt#!/usr/bin/env bash
# Demonstrate -- separator
# Run as: bash script.sh -v -- file1.txt -oddname.txt
VERBOSE=0
while getopts ':v' opt; do
case "$opt" in
v) VERBOSE=1 ;;
\?) echo "Unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1)) # removes -v and the '--' separator
echo "Verbose: $VERBOSE"
echo "Files to process:"
for f in "$@"; do
echo " -> $f"
doneEncapsulando getopts em uma função de biblioteca
Em scripts modulares, você pode encapsular getopts em uma função parse_args() que define variáveis globais (ou variáveis por referência). Isso mantém main() limpo e permite carregar o analisador a partir de outros scripts.
Regras principais desse padrão:
- Declare as variáveis das opções antes de chamar a função
- Use variáveis
globalou passe valores por meio de nameref (declare -n) - Retorne um código de saída diferente de zero para entradas inválidas, para que
mainpossa reagir
#!/usr/bin/env bash
# Global option variables
VERBOSE=0; OUTPUT=''; COUNT=1
parse_args() {
local opt
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
h) echo "Usage: $(basename "$0") [-v] [-n N] [-o FILE]"; exit 0 ;;
:) echo "Error: -$OPTARG needs a value" >&2; return 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; return 1 ;;
esac
done
shift $((OPTIND - 1))
ARGS=("$@") # leftover positional args stored in array
}
main() {
parse_args "$@" || exit 1
echo "verbose=$VERBOSE count=$COUNT output=${OUTPUT:--} args=${ARGS[*]}"
}
main "$@"Exemplo completo do mundo real: um arquivador de registros
Aqui está um script completo do mundo real que usa tudo o que foi abordado nesta lição: cadeia de opções com argumentos obrigatórios, modo silencioso de erro, uma função de uso, valores padrão, validação e o deslocamento com OPTIND.
Estude a estrutura — ela é o modelo que você deve seguir em todo script que escrever e que precise de uma interface CLI.
#!/usr/bin/env bash
# archive_logs.sh — compress and move logs older than N days
set -euo pipefail
DESTDIR='/tmp/log_archive'
DAYS=30
VERBOSE=0
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-d DAYS] [-o DIR] SOURCE_DIR
-d DAYS Archive logs older than DAYS (default: 30)
-o DIR Destination directory (default: /tmp/log_archive)
-v Verbose output
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':d:o:vh' opt; do
case "$opt" in
d) DAYS="$OPTARG" ;;
o) DESTDIR="$OPTARG" ;;
v) VERBOSE=1 ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
# Validation
[[ $# -lt 1 ]] && { echo "Error: SOURCE_DIR is required" >&2; usage 1; }
[[ "$DAYS" =~ ^[0-9]+$ ]] || { echo "Error: DAYS must be numeric" >&2; exit 1; }
SOURCE="$1"
[[ -d "$SOURCE" ]] || { echo "Error: '$SOURCE' is not a directory" >&2; exit 1; }
mkdir -p "$DESTDIR"
[[ $VERBOSE -eq 1 ]] && echo "Archiving logs older than $DAYS days from $SOURCE to $DESTDIR"
find "$SOURCE" -name '*.log' -mtime "+$DAYS" -print | while read -r f; do
gzip -c "$f" > "$DESTDIR/$(basename "$f").gz"
[[ $VERBOSE -eq 1 ]] && echo " archived: $f"
done
echo "Done."Verificação rápida: cadeia de opções de getopts
Leia a chamada de getopts a seguir e escolha a descrição correta de seu comportamento:
while getopts ':f:vq' opt; doRecapitulação da lição: domínio de getopts
Você aprendeu a criar interfaces profissionais de linha de comando em Bash usando getopts. Veja um resumo dos pontos principais:
- Sintaxe da cadeia de opções — letras sem dois-pontos são sinalizadores booleanos; dois-pontos após uma letra significam que ela exige um argumento; dois-pontos iniciais ativam o modo silencioso de erro.
- OPTARG — contém automaticamente o valor do argumento das opções que exigem um.
- OPTIND — use
shift $((OPTIND - 1))após o laço para expor os parâmetros posicionais restantes em$@. - Modo silencioso de erro — preferível em produção; trate você mesmo os casos
:(argumento ausente) e\?(opção desconhecida) para obter controle total. - Função
usage()— escreva sempre uma; imprima em stderr, encerre com 0 para-he com 1 para erros. - Sinalizadores combinados — getopts lida automaticamente com
-vqe-n5, sem código adicional. - Padrão modular — envolva getopts em uma função
parse_args()para criar scripts limpos e reutilizáveis.
Dominar getopts transforma seus scripts de ferramentas de finalidade única em programas CLI confiáveis e fáceis de usar, que seguem as convenções do Unix.
Perguntas Frequentes
A aula “Análise de opções e argumentos com getopts” é grátis?
Sim — o texto completo de “Análise de opções e argumentos com getopts” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de DevOps Bootcamp, atualize para CoddyKit PRO. O curso de DevOps Bootcamp inclui 4 aulas no total.
O que vou aprender em “Análise de opções e argumentos com getopts”?
Implemente interfaces de linha de comando profissionais usando getopts para opções curtas, argumentos obrigatórios e mensagens de uso. Você pratica DevOps Bootcamp com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar DevOps Bootcamp?
Nenhuma experiência prévia é necessária. DevOps Bootcamp no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Análise de opções e argumentos com getopts”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de DevOps Bootcamp?
Sim. Cada aula de DevOps Bootcamp inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Projeto de funções com escopo local e códigos de retorno
- Construção e carregamento de bibliotecas Bash reutilizáveis
- Análise de opções e argumentos com getopts
- Passagem de matrizes e mapas associativos entre funções