Padroneggiare l'Analisi degli Argomenti in Bash per Script Potenti
Analizza gli argomenti di Bash con parametri posizionali, getopts, cicli per opzioni lunghe, valori predefiniti e messaggi di errore chiari.
Padroneggiare l'Analisi degli Argomenti in Bash per Script Potenti
Gli argomenti da riga di comando rendono flessibili i tuoi script Bash. Quando l'analisi degli argomenti in Bash è debole, ti ritrovi a modificare le variabili all'interno dello script ogni volta che hai bisogno di un file, host o modalità diversa.
Questa guida ti mostra come gestire argomenti posizionali, opzioni brevi con getopts e opzioni lunghe con un ciclo while/case. L'obiettivo è uno script che rifiuti input errati precocemente e ti dica esattamente come eseguirlo.
Le Basi: Argomenti Posizionali
Prima di affrontare flag e opzioni nominate, è cruciale capire come Bash gestisce argomenti semplici e sequenziali.
| Variabile | Descrizione | Esempio se chiamato come ./script.sh foo bar |
|---|---|---|
$0 |
Il nome dello script stesso | ./script.sh |
$1, $2, ... |
Il primo, secondo, ecc., argomento posizionale | foo, bar |
$# |
Il conteggio degli argomenti posizionali | 2 |
$@ |
Tutti gli argomenti posizionali, trattati come stringhe separate | foo bar |
$* |
Tutti gli argomenti posizionali, trattati come un'unica stringa | foo bar |
Esempio: Controllo Posizionale Semplice
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Utilizzo: $0 <file_sorgente> <directory_destinazione>"
exit 1
fi
SOURCE="$1"
DESTINATION="$2"
echo "Copia di $SOURCE in $DESTINATION..."
# cp "$SOURCE" "$DESTINATION"
Analisi Standard con getopts per Opzioni Brevi
Per script professionali che richiedono opzioni come -v (verbose) o -f <file>, l'utilità integrata getopts è il metodo canonico e più affidabile in Bash puro. È progettata specificamente per opzioni brevi (a carattere singolo).
Come Funziona getopts
getopts legge le opzioni in sequenza, impostando la variabile designata (di solito OPT) sull'opzione trovata e inserendo il valore di qualsiasi argomento (se richiesto) nella variabile OPTARG.
- Stringa di Opzioni (OPTSTRING): Definisce le opzioni valide. Se un'opzione richiede un argomento (ad es.,
-f nomefile), segui il carattere con due punti (:). Esempio:vho:permette-v,-he-oche richiede un valore. OPTIND: Un indice Bash interno che tiene traccia del prossimo argomento da elaborare. Deve essere inizializzato a 1 (che è il valore predefinito, ma a volte resettato in script complessi).
Modello Pratico per getopts
Questo modello gestisce tre opzioni: -v (flag), -h (flag) e -f (opzione che richiede un valore).
#!/bin/bash
# --- Valori Predefiniti ---
VERBOSE=0
FILENAME="default.txt"
# --- Funzione di Utilizzo ---
usage() {
echo "Utilizzo: $0 [-v] [-h] [-f <file>] <input>"
exit 1
}
# --- Ciclo di Analisi degli Argomenti ---
while getopts ":vhf:" OPT; do
case "$OPT" in
v)
VERBOSE=1
echo "Modalità verbose abilitata."
;;
h)
usage
;;
f)
# OPTARG contiene l'argomento fornito a -f
FILENAME="$OPTARG"
echo "Nome file di output impostato su: $FILENAME"
;;
\?)
# Gestisce opzioni non riconosciute
echo "Errore: Opzione non valida -$OPTARG" >&2
usage
;;
:)
# Gestisce argomenti mancanti per opzioni che ne richiedono uno (ad es., -f senza nomefile)
echo "Errore: L'opzione -$OPTARG richiede un argomento." >&2
usage
;;
esac
done
# --- Spostamento degli Argomenti Posizionali ---
# Dopo che getopts termina, OPTIND contiene l'indice del primo argomento non opzione.
# Usiamo shift per scartare tutte le opzioni analizzate, lasciando solo gli argomenti posizionali ($1, $2, ecc.).
shift $((OPTIND - 1))
# Verifica se l'argomento posizionale richiesto (INPUT) è presente
INPUT_DATA="$1"
if [ -z "$INPUT_DATA" ]; then
echo "Errore: Dati di input richiesti."
usage
fi
echo "---"
echo "Elaborazione input: $INPUT_DATA"
echo "Stato verbose: $VERBOSE"
Suggerimento: Usa sempre
shift $((OPTIND - 1))immediatamente dopo il ciclowhile getoptsper separare pulitamente le opzioni dagli argomenti posizionali rimanenti.
Gestione delle Opzioni Lunghe come --option
Il getopts integrato di Bash puro supporta solo opzioni brevi. Per gestire opzioni lunghe moderne (ad es., --verbose, --output-file=data.log), devi implementare un ciclo di analisi personalizzato usando while e case con il comando shift.
Questo metodo richiede una gestione degli argomenti più esplicita.
Analizzatore Personalizzato per Opzioni Lunghe
#!/bin/bash
# --- Valori Predefiniti ---
VERBOSE=0
OUTPUT_FILE=""
# Funzione personalizzata per mostrare l'utilizzo (omessa per brevità)
# usage() { ... }
while [ "$#" -gt 0 ]; do
case "$1" in
--verbose)
VERBOSE=1
shift
;;
--output-file)
# Richiede due shift: uno per il flag, uno per il valore
if [ -z "${2:-}" ]; then
echo "Errore: --output-file richiede un valore."
exit 1
fi
OUTPUT_FILE="$2"
shift 2
;;
--help)
usage
;;
-*)
echo "Errore: Opzione sconosciuta $1" >&2
exit 1
;;
*)
# Trovato il primo argomento posizionale, ferma l'analisi delle opzioni
break
;;
esac
done
# Gli argomenti rimanenti sono ora disponibili come $1, $2, ecc.
# ... La logica dello script continua ...
if [ "$OUTPUT_FILE" ]; then
echo "Dati reindirizzati a $OUTPUT_FILE"
fi
Se il tuo script accetta argomenti posizionali dopo le opzioni, continua l'analisi fino a raggiungere -- o il primo argomento non opzione. Una convenzione comune è lasciare che -- significhi "ferma l'analisi delle opzioni ora":
while [ "$#" -gt 0 ]; do
case "$1" in
--)
shift
break
;;
--verbose)
VERBOSE=1
shift
;;
*)
break
;;
esac
done
Avanzato: Gestione delle Opzioni Lunghe Chiave-Valore (--key=value)
Se preferisci lo stile UNIX standard in cui gli argomenti vengono passati usando un segno di uguale, devi usare la sostituzione dei parametri per dividere l'argomento.
while [ "$#" -gt 0 ]; do
case "$1" in
--limit=*)
LIMIT_VAL="${1#*=}" # Rimuovi tutto fino a e incluso '='
echo "Limite impostato su: $LIMIT_VAL"
shift
;;
# ... altre opzioni ...
esac
done
Migliori Pratiche per Script Robusto
A. Combinare Opzioni Brevi e Lunghe
Per massima flessibilità, gli script esperti spesso combinano l'affidabilità di getopts per le opzioni brevi con il ciclo personalizzato while/case per le opzioni lunghe. Il ciclo delle opzioni lunghe viene eseguito per primo, consumando i flag lunghi, e poi gli argomenti rimanenti (incluse le opzioni brevi) vengono elaborati da getopts.
Tuttavia, un modello più pulito e comune è elaborare tutti gli argomenti in un unico ciclo personalizzato robusto che cerca sia -o che --option, spostandosi di conseguenza.
B. Gestione degli Errori e Utilizzo
Fornisci sempre una funzione usage chiara che spieghi gli argomenti e le opzioni richieste dallo script. Questa funzione dovrebbe essere chiamata quando:
- L'utente richiede aiuto (ad es.,
-ho--help). - Un argomento richiesto è mancante.
- Viene fornita un'opzione non valida o sconosciuta.
Assicurati che lo script esca con uno stato diverso da zero in caso di errore (exit 1) e invii i messaggi di errore allo Standard Error (>&2).
C. Valori Predefiniti
Inizializza tutte le variabili di configurazione all'inizio dello script con valori predefiniti sensati. Questo rende il tuo script prevedibile anche se non vengono passati argomenti opzionali.
# Inizializza sempre le variabili prima dell'analisi
LOG_LEVEL="info"
FORCE=0
Conclusione
Usa argomenti posizionali per valori semplici richiesti, getopts per opzioni brevi portabili e un ciclo personalizzato while/case quando hai bisogno di opzioni lunghe. Testa valori mancanti, flag sconosciuti e argomenti con spazi prima di fidarti dello script nell'automazione.