0Pricing
Linux Command Line & Bash Scripting Mastery · 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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery, passa a CoddyKit PRO. Il corso Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?

Non è richiesta alcuna esperienza precedente. Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?

Sì. Ogni lezione Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery