0Pricing
Linux Command Line & Bash Scripting Mastery · Aula

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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Linux Command Line & Bash Scripting Mastery 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 OPTIND e OPTARG

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
done

Definindo 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' — -a exige um argumento; -b e -c nã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 / --help e com o código 1 para uso inválido
  • Chamar usage 1 nos caminhos de erro e usage 0 no 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!"
done

Combinando 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 -q equivale a -vq
  • -n 5 -v equivale a -n5 -v ou -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"
done

Encapsulando 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 global ou passe valores por meio de nameref (declare -n)
  • Retorne um código de saída diferente de zero para entradas inválidas, para que main possa 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; do

Recapitulaçã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 -h e com 1 para erros.
  • Sinalizadores combinados — getopts lida automaticamente com -vq e -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 Linux Command Line & Bash Scripting Mastery, atualize para CoddyKit PRO. O curso de Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?

Nenhuma experiência prévia é necessária. Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?

Sim. Cada aula de Linux Command Line & Bash Scripting Mastery 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

  1. Projeto de funções com escopo local e códigos de retorno
  2. Construção e carregamento de bibliotecas Bash reutilizáveis
  3. Análise de opções e argumentos com getopts
  4. Passagem de matrizes e mapas associativos entre funções
← Voltar para Linux Command Line & Bash Scripting Mastery