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
OPTINDeOPTARG
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
doneDefinire 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'—-arichiede un argomento;-be-cno':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 1nei percorsi di errore eusage 0dal 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!"
doneCombinare le flag nella riga di comando
getopts gestisce automaticamente le flag brevi combinate scritte senza spazi, secondo la convenzione Unix standard:
-v -qequivale a-vq-n 5 -vequivale a-n5 -vo-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"
doneRacchiudere 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
globalo passate i valori tramite nameref (declare -n) - Restituite un codice di uscita diverso da zero in caso di input errato, così
mainpuò 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; doRiepilogo 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
-he con 1 in caso di errore. - Flag combinate — getopts gestisce automaticamente
-vqe-n5senza 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
- Progettazione di funzioni con ambito locale e codici di ritorno
- Creazione e sourcing di librerie Bash riutilizzabili
- Analisi di flag e argomenti con getopts
- Passaggio di array e mappe associative tra funzioni