0Pricing
DevOps Bootcamp · Lezione

Analisi di flag e argomenti con getopts

Implementi interfacce a riga di comando professionali usando getopts per opzioni brevi, argomenti obbligatori e messaggi di utilizzo.

Analisi di flag e argomenti con getopts è una lezione DevOps Bootcamp gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento DevOps Bootcamp, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso DevOps Bootcamp include 4 lezioni in totale.

Perché esiste getopts

Prima o poi ogni script reale deve accettare opzioni come -v, -o output.txt o -n 5. Analizzarle manualmente con $1, $2… diventa rapidamente fragile.

getopts è il comando incorporato standard POSIX che gestisce in modo affidabile le opzioni brevi (-a, -b), incluse quelle che accettano un argomento. È incorporato in ogni shell POSIX, quindi non richiede dipendenze.

  • Gestisce i flag combinati: -vn 5 = -v -n 5
  • Segnala le opzioni sconosciute in modo appropriato
  • Imposta automaticamente le variabili standard OPTIND e OPTARG

In questa lezione costruirete da zero una CLI completa e professionale utilizzando getopts.

La sintassi di getopts

La sintassi di base consiste in un ciclo while che chiama getopts a ogni iterazione:

while getopts "optstring" varname; do
  case "$varname" in
    ...
  esac
done
  • optstring — una stringa che elenca le lettere delle opzioni accettate. I due punti dopo una lettera indicano che l'opzione richiede un argomento.
  • varname — riceve la lettera dell'opzione corrente a ogni iterazione.
  • OPTARG — viene impostata automaticamente sul valore dell'argomento quando dopo la lettera compare un due punti.
  • OPTIND — indice del prossimo argomento da elaborare; dopo il ciclo, eseguite lo shift con shift $((OPTIND - 1)) per rendere accessibili i parametri posizionali rimanenti.
#!/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

Definire un optstring

optstring è una dichiarazione compatta del contratto della vostra CLI. Ogni carattere rappresenta un flag accettato.

  • 'abc' — accetta -a, -b, -c (senza argomenti)
  • 'a:bc' — -a richiede un argomento; -b e -c no
  • ':abc' — i due punti iniziali abilitano la modalità di gestione silenziosa degli errori (lo script gestisce le opzioni errate invece di lasciare che la shell visualizzi un messaggio)

La modalità silenziosa è preferibile negli script di produzione perché offre il pieno controllo sui messaggi di errore e sui codici di uscita.

#!/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 argomenti obbligatori

Quando nel valore di optstring una flag è seguita da due punti, getopts memorizza il suo valore in OPTARG. L'utente può scrivere l'argomento con o senza uno spazio:

  • -o report.txt
  • -oreport.txt

Le due forme vengono analizzate allo stesso modo. Questo è uno dei principali vantaggi rispetto all'analisi manuale con $1/shift.

In modalità silenziosa (con ':' all'inizio di optstring), quando manca un argomento getopts imposta varname su : e OPTARG sulla lettera dell'opzione: è l'ideale per mostrare un messaggio di errore mirato.

#!/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>}"

Superare le opzioni con OPTIND

Al termine di getopts, OPTIND contiene l'indice del primo argomento che non è un'opzione. Usate shift per rimuovere tutte le opzioni elaborate, così $1, $2… fanno riferimento ai parametri posizionali rimanenti (ad esempio, i nomi dei file).

L'idioma è sempre:

shift $((OPTIND - 1))

Dopo lo shift, $@ contiene solo gli argomenti che non erano flag, ovvero gli operandi del 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: $*"

Scrivere una funzione usage

Uno script professionale fornisce sempre una funzione usage() che stampa un messaggio di aiuto e termina l'esecuzione. La convenzione è:

  • Stampare su stderr (fd 2), così l'output inoltrato tramite pipe non viene alterato
  • Terminare con codice 0 per -h / --help, e con codice 1 in caso di utilizzo non valido
  • Chiamare usage 1 nei percorsi di errore e usage 0 dal gestore di -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:--}"

Valori predefiniti e convalida

Dopo l'analisi, convalidate gli input e impostate i valori predefiniti prima di eseguire qualsiasi operazione reale. Mantenete separata la fase di analisi (il ciclo) dalla fase logica. In questo modo entrambe le sezioni saranno più facili da leggere e testare.

  • Usate ${VAR:-default} per i valori predefiniti inline
  • Convalidate gli argomenti numerici con un'espressione regolare o un controllo aritmetico
  • Verificate che le opzioni obbligatorie siano state effettivamente fornite
#!/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

Combinare le flag nella riga di comando

getopts gestisce automaticamente le flag brevi combinate scritte senza spazi, secondo la convenzione Unix standard:

  • -v -q equivale a -vq
  • -n 5 -v equivale a -n5 -v o -vn5

Non dovete scrivere codice aggiuntivo per supportarle: getopts analizza automaticamente ogni carattere di una stringa di opzioni combinata. Questo è un altro importante motivo per preferire getopts all'analisi manuale.

#!/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"

Gestire il separatore doppio trattino

I comandi Unix accettano -- (doppio trattino) come segnale esplicito per interrompere l'elaborazione delle opzioni. Tutto ciò che segue -- viene trattato come argomento posizionale, anche se sembra una flag.

getopts si interrompe automaticamente quando incontra --. Dopo shift $((OPTIND - 1)), il doppio trattino è scomparso e $@ contiene solo gli operandi.

Questo è importante per gli script che operano su nomi di file che potrebbero iniziare con un trattino, ad esempio:

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

Racchiudere getopts in una funzione di libreria

Negli script modulari, potete incapsulare getopts in una funzione parse_args() che imposta variabili globali (o nameref). In questo modo main() rimane pulita e potete caricare l'analizzatore da altri script.

Regole fondamentali per questo schema:

  • Dichiarate le variabili delle opzioni prima di chiamare la funzione
  • Usate variabili global o passate i valori tramite nameref (declare -n)
  • Restituite un codice di uscita diverso da zero in caso di input errato, così main può reagire
#!/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 "$@"

Esempio completo realistico: un archiver di log

Ecco uno script completo e realistico che utilizza tutto ciò che è stato illustrato in questa lezione: optstring con argomenti obbligatori, modalità silenziosa degli errori, una funzione usage, valori predefiniti, convalida e lo shift di OPTIND.

Studiate la struttura: è il modello da seguire in ogni script che scriverete e che richieda un'interfaccia 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 rapida: optstring di getopts

Leggete la seguente chiamata a getopts e scegliete la descrizione corretta del suo comportamento:

while getopts ':f:vq' opt; do

Riepilogo della lezione: padroneggiare getopts

Avete imparato a creare interfacce professionali a riga di comando in Bash utilizzando getopts. Ecco un riepilogo dei punti fondamentali:

  • Sintassi di optstring — le lettere senza due punti sono flag booleane; i due punti dopo una lettera indicano che questa richiede un argomento; i due punti iniziali abilitano la modalità silenziosa degli errori.
  • OPTARG — contiene automaticamente il valore dell'argomento per le opzioni che ne richiedono uno.
  • OPTIND — usate shift $((OPTIND - 1)) dopo il ciclo per rendere accessibili in $@ i parametri posizionali rimanenti.
  • Modalità silenziosa degli errori — preferibile in produzione; gestite autonomamente i casi : (argomento mancante) e \? (opzione sconosciuta) per avere il pieno controllo.
  • Funzione usage() — scrivetela sempre; stampate su stderr, uscite con 0 per -h e con 1 in caso di errore.
  • Flag combinate — getopts gestisce automaticamente -vq e -n5 senza codice aggiuntivo.
  • Schema modulare — racchiudete getopts in una funzione parse_args() per ottenere script puliti e riutilizzabili.

Padroneggiare getopts trasforma i vostri script da strumenti monouso in programmi CLI affidabili e intuitivi, conformi alle convenzioni Unix.

Domande Frequenti

La lezione «Analisi di flag e argomenti con getopts» è gratuita?

Sì — il testo completo di «Analisi di flag e argomenti con getopts» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso DevOps Bootcamp, passa a CoddyKit PRO. Il corso DevOps Bootcamp include 4 lezioni in totale.

Cosa imparerò in «Analisi di flag e argomenti con getopts»?

Implementi interfacce a riga di comando professionali usando getopts per opzioni brevi, argomenti obbligatori e messaggi di utilizzo. Eserciti DevOps Bootcamp con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare DevOps Bootcamp?

Non è richiesta alcuna esperienza precedente. DevOps Bootcamp su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Analisi di flag e argomenti con getopts»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione DevOps Bootcamp?

Sì. Ogni lezione DevOps Bootcamp include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Progettazione di funzioni con ambito locale e codici di ritorno
  2. Creazione e sourcing di librerie Bash riutilizzabili
  3. Analisi di flag e argomenti con getopts
  4. Passaggio di array e mappe associative tra funzioni
← Torna a DevOps Bootcamp