## page was renamed from ParsingDellaRigaDiComando
## page was renamed from GuidaWiki/DocumentazioneModello
#format wiki
#LANGUAGE it
<
>
<>
<>
<>
= Introduzione =
Il '''[[https://it.wikipedia.org/wiki/Parsing|parsing]]''' è la procedura con cui un comando, uno script o più genericamente un programma, analizza le istruzioni che l'utente fornisce quando lo chiama usando il [[https://wiki.ubuntu-it.org/AmministrazioneSistema/Terminale|terminale]].
Queste istruzioni sono una opportuna combinazione di opzioni e parametri e modificano il comportamento del programma a cui vengono passate.
A esempio, per lanciare il comando '''ls''' da terminale una sinossi comune è la seguente:{{{
ls -a -l --color=auto file
}}}
Ul generico comando è composto dal nome del comando stesso seguito da una serie di argomenti detti ''parametri posizionali''.<
>
Questi ultimi possono essere suddivisi in alcune categorie logiche:
* '''opzioni corte''': consistono in un trattino seguito da una singola lettera (ad esempio `-a` nel comando precedente). Se vi sono più opzioni corte, le si può raggruppate insieme (ad esempio `-al` nel comando precedente).
* '''opzioni lunghe''': possono essere espresse nello ''stile '''[[https://it.wikipedia.org/wiki/GNU|Gnu]]''''', consistente in due trattini seguiti dal nome completo dell'opzione (as esempio `--color` nel comando precedente), oppure nello ''stile '''[[https://it.wikipedia.org/wiki/XFree86|XF86]]''''', che prevede un singolo trattino seguito dal nome completo dell'opzione.
* '''parametri''': specificano le azioni che devono svolgere le opzioni e vengono scritti subito dopo di esse. Generalmente, per le opzioni corte sono scritti direttamente attaccati all'opzione o separatati da uno spazio; per le opzioni lunghe sono separati da uno spazio o dal carattere «`=`» (ad esempio , `=auto` nel comando precedente).
Il comando precedente è equivalente al seguente:{{{
ls --color=auto -la file
}}}
In questo caso tutte le opzioni corte sono state riunite ed è stato cambiato l'ordine delle opzioni.
{{{#!wiki important
Non tutti i comandi accettano un ordine casuale delle opzioni.
}}}
La difficoltà del ''parsing'' è proprio nel riconoscimento delle varie opzioni e parametri, a prescindere dalla loro posizione nella sintassi della chiamata.
Per agevolare questa procedura, sono disponibili due utili comandi da usare nel terminale:
* '''getopt''': ## concisa descrizione del comando
* '''getopts''': ## concisa descrizione del comando
## Importante, dattilografa due righe per differenziarne l'uso, o su quale usare di volta in volta.
<>
= getopt =
'''getopt''' analizza una stringa di parametri e ne restituisce una versione ''canonica'' e ''standardizzata'' che può essere analizzata più facilmente. Questa analisi successiva viene eseguita in un [[http://www.pluto.it/files/ildp/guide/abs/loops.html#WHILELOOPREF|ciclo while]], all'interno del quale le varie scelte sono effettuate in un [[http://www.pluto.it/files/ildp/guide/abs/testbranch.html|costrutto case]].
== Pro ==
* Supporta sia le opzioni corte, sia quelle lunghe. Di quest'ultime, supporta sia lo ''stile GNU'', sia lo ''stile XF86''.
* È in grado di gestire opzioni con parametri che siano obbligatori o facoltativi.
== Contro ==
* La versione descritta in questa guida non è un built-in della shell, ma è inclusa nel pacchetto ''util-linux'' e precedentemente nella libreria ''glibc'' (cioè, la ''GNU lib c''). Questa versione è presente di default in Ubuntu e in tutte le derivate ufficiali. Nelle versioni di ''Linux'' in cui non fosse presente, può essere facilmente installata.<
>
Per verificare che la versione nel proprio sistema sia quella descritta in questa guida, si può controllare che l'output del seguente comando sia uguale a 4:{{{
getopt --test || echo $?}}}
== Sintassi ==
'''getopt''' può essere chiamato con tre diverse sintassi:
* La sintassi minimale è:
{{{
getopt optstring parameters
}}}
La stringa '''optstring''' elenca le opzioni nel formato corto che si possono incontrare durante il parsing. Questa stringa può essere racchiusa tra doppi apici e al suo interno i nomi delle opzioni possono essere elencati senza separatori. Se l'opzione prevede un parametro obbligatorio, il carattere che la indica è seguito dai due punti; se il parametro è opzionale, è seguito da una coppia di doppi punti.<
>
La stringa '''parameters''' contiene gli argomenti su cui operare. Generalmente si pone uguale alla stringa dei parametri posizionali passati allo script, cioè "$@". Se si vuole scrivere una stringa alternativa, questa non va racchiusa tra apici, né singoli né doppi.
* Un'estensione della precedente sintassi è data da:
{{{
getopt [options] [--] optstring parameters
}}}
Le parti racchiuse tra parentesi quadre sono opzionali. Se mancano, si riottiene la sintassi precedente.<
>
La stringa '''options''', descritta in dettaglio nella tabella successiva, contiene una serie di opzioni e rispettivi parametri che modificano il funzionamento del comando.
* Infine, la sintassi più articolata è data da:
{{{
getopt [options] -o|--options optstring [options] [--] parameters
}}}
In questo caso la stringa '''options''' tra parentesi quadre può ricorrere due volte.<
>
La stringa '''-o|--options''' indica che le opzioni a sinistra e destra della barra verticale sono equivalenti.<
>
La stringa '''optstring''' ha lo stesso significato visto nelle precedenti sintassi.
Le opzioni e rispettivi parametri che possono essere presenti nella stringa '''options''' tra parentesi quadre sono i seguenti:
||'''Opzione''' ||<:60%>'''Descrizione''' ||
||<#f7f7f7> '''-l|--long|--longoptions longopts''' || Indica che durante il parsing si potranno incontrare opzioni lunghe, i cui nomi vengono specificati nella stringa '''longopts'''. Questa stringa può essere racchiusa tra doppi apici e i nomi al suo interno vanno separati con una virgola. Se il nome che indica l'opzione lunga è seguito dai due punti, questa accetta un parametro obbligatorio; se è seguito da una coppia di doppi punti, accetta un parametro facoltativo. ||
||<#f7f7f7> '''-a|--alternative''' || Abilita il riconoscimento delle opzioni lunghe nello ''stile XF86'', quindi con un singolo trattino iniziale. ||
||<#f7f7f7> '''-n|--name progname''' || Imposta il nome dello script al contenuto della variabile ''progname''. ||
||<#f7f7f7> '''-q|--quiet''' || Disabilita l'output automatico degli errori. ||
||<#f7f7f7> '''-Q|--quiet-output''' || Disabilita la produzione della stringa normalizzata dei parametri passati allo script, ma gli errori incontrati nel parsing vengono ancora riportati. ||
== Esempi di chiamate al comando ==
I seguenti esempi mostrano come utilizzare le tre sintassi viste nel paragrafo precedente:
* Un esempio di invocazione del comando secondo la sintassi minimale è:
{{{
getopt "hf:d::" "$@"
}}}
Con questa sintassi vengono accettate le seguenti opzioni: '''h''' senza parametro, '''f''' con un parametro obbligatorio e '''d''' con un parametro facoltativo.
* Un esempio di invocazione del comando con la seconda sintassi è:
{{{
getopt -l "help,file:,dir::" -- "hf:d::" "$@"
}}}
Con questa sintassi vengono accettate anche le opzioni nella versione lunga: '''help''' senza parametro, '''file''' con un parametro obbligatorio e '''dir''' con un parametro facoltativo.
* Un esempio di invocazione del comando seguendo la sintassi più articolata è:
{{{
getopt -l "help,file:,dir::" -o "hf:d::" --alternative -- "$@"
}}}
Analogo all'esempio precedente, ma con questa sintassi le opzioni possono essere indicate anche nello ''stile XF86''.
È importante sottolineare che, negli argomenti passati allo script, le opzioni e i relativi parametri rispettano le seguenti regole:
* Se un'opzione corta accetta un parametro obbligatorio, opzione e parametro possono essere scritti attaccati o separati da uno spazio.<
>Se il parametro è facoltativo, devono essere scritti attaccati.
* Se un'opzione lunga accetta un parametro obbligatorio, opzione e parametro devono essere separati da uno spazio o dal carattere «=».<
>Se il parametro è facoltativo, devono essere separati dal carattere «=».
* Le opzioni corte possono essere raggruppate e scritte in qualsiasi ordine, con l'accortezza di lasciare accoppiate ai propri parametri quelle che li prevedono.
* '''getopt''' riconosce qualsiasi abbreviazione non ambigua delle opzioni nel formato lungo. Facendo riferimento agli esempi precedenti, l'opzione `--fi` sarà quindi riconosciuta come `--file` poiché non c'è rischio di ambiguità con altre opzioni.
== Esempio d'uso ==
Lo script che segue accetta l'opzione '''-a''' senza parametro, l'opzione '''-b''' con parametro obbligatorio e l'opzione '''-c''' con parametro facoltativo. Sono accettate anche le rispettive varianti lunghe nello ''stile Gnu'' (ovvero precedute da due trattini) '''--a-lunga''', '''--b-lunga''' e '''--c-lunga'''.
{{{
#!
#! /bin/bash
getopt --test > /dev/null
if [[ $? -ne 4 ]]; then
echo "La versione di getopt non è quella del pacchetto utils-linux"
exit 1
fi
OPZIONI_CORTE=ab:c::
OPZIONI_LUNGHE=a-lunga,b-lunga:,c-lunga::
TEMP=$(getopt --options="$OPZIONI_CORTE" --longoptions="$OPZIONI_LUNGHE" --name "prova_getopt.sh" -- "$@")
if [[ $? -ne 0 ]]; then
echo "getopt ha fallito il parsing"
exit 2
fi
echo "Versione canonica dei parametri prodotta da getopt: "$TEMP""
eval set -- "$TEMP"
while true
do
case "$1" in
-a|--a-lunga)
echo "Opzione '$1', senza argomento."
shift
;;
-b|--b-lunga)
echo "Opzione '$1', con argomento '$2'."
shift 2
;;
-c|--c-lunga)
case "$2" in
"")
echo "Opzione '$1', senza argomento."
shift 2
;;
*)
echo "Option c, con argomento '$2'."
shift 2
;;
esac
;;
--)
shift
break
;;
*)
echo "Errore interno!"
exit ;;
esac
done
if [[ $# != 0 ]]
then
echo "Argomenti rimanenti:"
for i in "$@"
do
echo "--> '$i'"
done
fi
}}}
Supponendo di aver salvato lo script con il nome `prova_getopt.sh`, di seguito vengono mostrati due differenti modi di chiamarlo e i rispettivi output prodotti:
* Opzione '''-a''' più due argomenti:{{{
$ ./prova_getopt.sh foo -a bar
Versione canonica dei parametri prodotta da getopt: -a -- 'foo' 'bar'
Opzione '-a', senza argomento.
Argomenti rimanenti:
--> 'foo'
--> 'bar'
}}}
Il parametro `bar` non viene associato all'opzione '''-a''', in quanto questa opzione non accetta parametri. Viene invece interpretato come argomento a sé stante ed elencato inseme a `foo` tra gli argomenti rimanenti dopo il parsing.
* Opzione '''-b''' con parametro, più due argomenti::{{{
$ ./prova_getopt.sh -b 5 bar foo
Versione canonica dei parametri prodotta da getopt: -b '5' -- 'bar' 'foo'
Opzione '-b', con argomento '5'.
Argomenti rimanenti:
--> 'bar'
--> 'foo'
}}}
Per `foo` e `bar` si ha lo stesso comportamento del comando precedente. L'argomento `5` invece viene interpretato come parametro dell'opzione '''-b'''. Visto che per questa opzione il parametro è obbligatorio, si può usare la sintassi equivalente `-b5`.
== Considerazioni sull'esempio d'uso ==
* I due modi di chiamare lo script d'esempio illustrati nel paragrafo precedente possono essere accorpati come segue:{{{
$ ./prova_getopt.sh -ab5 foo bar
Versione canonica dei parametri prodotta da getopt: -a -b '5' -- 'foo' 'bar'
Opzione '-a', senza argomento.
Opzione '-b', con argomento '5'.
Argomenti rimanenti:
--> 'foo'
--> 'bar'
}}}
* La posizione dei parametri passati allo script può variare secondo tutte le combinazioni consistenti con la sintassi descritta precedentemente, ad esempio:{{{
$ ./prova_getopt.sh foo -b5 bar -a
Versione canonica dei parametri prodotta da getopt: -b '5' -a -- 'foo' 'bar'
Opzione '-b', con argomento '5'.
Opzione '-a', senza argomento.
Argomenti rimanenti:
--> 'foo'
--> 'bar'
}}}
* L'opzione con parametro obbligatorio '''-b''' ha due sintassi equivalenti in versione lunga:{{{
$ ./prova_getopt.sh --b-lunga 5
}}}{{{
$ ./prova_getopt.sh --b-lunga=5
}}}
* L'unica sintassi valida per l'opzione corta '''-c''', che accetta un parametro opzionale, è quella in cui opzione e parametro sono scritti attaccati:{{{
$ ./prova_getopt.sh -c6
}}}
* La sintassi equivalente dell'opzione '''-c''' in versione lunga richiede che opzione e parametro siano separati dal carattere «`=`»:{{{
$ ./prova_getopt.sh --c-lunga=6
}}}
* Se si vogliono passare parametri posizionali interpretabili come opzioni, questi vanno scritti dopo i doppi trattini:
{{{
$ ./prova_getopt.sh foo -ab5 -- -car -bar -6
Versione canonica dei parametri prodotta da getopt: -a -b '5' -- 'foo' '-car' '-bar' '-6'
Opzione '-a', senza argomento.
Opzione '-b', con argomento '5'.
Argomenti rimanenti:
--> 'foo'
--> '-car'
--> '-bar'
--> '-6'
}}}
Senza il doppio trattino, infatti, `-6` verrebbe interpretata come opzione non permessa, mentre `-car` e `-bar` rispettivamente come opzioni '''-c''' e '''-b''', entrambe con `ar` come parametro.
* La porzione di codice:{{{
getopt --test > /dev/null
if [[ $? -ne 4 ]]; then
echo "La versione di getopt non è quella del pacchetto utils-linux"
exit 1
fi}}} serve per verificare che la versione di '''getopt''' sia quella descritta in questa guida. È superflua per Ubuntu e le sue derivate, ma permette di verificare che lo script sia correttamente utilizzabile anche in altre generiche distribuzioni di ''Linux''.
* La riga seguente visualizza la riorganizzazione dei parametri nella versione canonica prodotta da '''getopt''':{{{
echo "Versione canonica dei parametri prodotta da getopt: "$TEMP" "}}}
Ai fini del funzionamento dello script è superflua.
* L'istruzione seguente sostituisce i parametri posizionali passati allo script con la stringa `TEMP`, che è la loro versione ''canonica'':{{{
eval set -- "$TEMP"`}}}
In alcuni script è possibile che manchi l'istruzione '''eval'''. In questo caso, sono script non portabili pensati per [[https://it.wikipedia.org/wiki/Berkeley_Software_Distribution|BSD]]. La versione in cui è presente anche '''eval''' risulta portabile e deve essere preferita. Infine, le doppie virgolette che racchiudono `$TEMP` sono fondamentali.
* Il comando '''shift''' viene utilizzato all'interno del costrutto ''case'' per avanzare nella lettura dei parametri posizionali passati allo script. Questo comando ha l'effetto di far slittare verso sinistra i parametri posizionali, eliminandoli:
* Nel caso di un'opzione senza parametro, si slitta di una posizione.
* Nel caso dei due trattini `--` si slitta di una posizione e si interrompe il parsing.
* Nel caso di una opzione con parametro facoltativo, si slitta di due posizioni.
* Il costrutto ''case'' nidificato è un esempio di come si gestisce un'opzione che ha un parametro facoltativo.
<>
= getopts =
== Pro ==
* È un built-in della shell, quindi:
* è definito nello standard POSIX e non c'è bisogno di fare attenzione alle sue diverse implementazioni.
* Non ha bisogno di programmi esterni per accedere ai parametri posizionali.
* Può avere accesso diretto alle variabili della shell, che può usare per fare il parsing.
== Contro ==
* Può fare il parsing solo delle opzioni corte. Se lo script prevede l'uso di opzioni lunghe, sia nello ''stile GNU'' sia nello ''stile XF86'', '''getopts''' non è la scelta opportuna.
* Non supporta le opzioni con parametri facoltativi.
== Funzionamento ==
La sintassi del comando è:
{{{
getopts optstring varname [args]
}}}
in cui
||'''Parametro''' ||<:>'''Descrizione''' ||
||<:> '''optstring''' || È una stringa che istruisce il comando relativamente a quali opzioni aspettarsi e quando siano previsti i relativi parametri.||
||<:> '''varname''' || È una stringa che rappresenta il nome della variabile della shell in cui il comando ''getopts'' inserisce il valore delle opzioni lette. ||
||<:> '''args''' || È una stringa facoltativa. Di default, il comando fa il parsing dei parametri posizionali, cioè della stringa $@; se è presente una stringa ''args'', farà il parsing dei parametri contenuti in quest'ultima. ||
'''getopts''' viene quindi istruito sulle opzioni e gli eventuali parametri che si può aspettare tramite '''optstring'''.<
>La sintassi di questa stringa è molto semplice.
* Ogni opzione che si vuole aggiungere, viene indicata con la relativa lettera. Non sono consentiti i caratteri ':' e '?'.
* Se l'opzione prevede un parametro associato, il carattere che la indica è seguito dai due punti. Quindi, se si vuole permettere l'opzione 'f' con un parametro associato, nella stringa '''optstring''' si aggiungerà la sequenza 'f:'
* Il comando ''getopts'' può essere impostato nella modalità silenziosa, usando i due punti ':' come prefisso di ''optstring''. Se questo carattere è assente, ''getopts'' è in modalità verbosa. La differenza è che nel seconda modalità produce messaggi di errori automatici durante il parsing. Generalmente, si opta per la modalità silenziosa e la gestione autonoma dei messaggi d'errore. Inoltre, tramite la variabile '''OPTERR''' (vedi sotto) si può comunque silenziare la stampa dei messaggi di errore nella modalità verbosa.
Quindi, se desideriamo che il comando si aspetti di incontrare nel parsing le opzione 'v' ed 'h' senza parametri associati e l'opzione 'f' con un parametro associato, '''optstring''' sarebbe uguale a "vhf:" per la modalità verbosa e uguale a ":vhf:" per quella silenziosa.
Per il suo funzionamento, '''getopts''' usa le seguenti variabili:
||'''Variabile''' ||<:>'''Descrizione''' ||
||<:> '''OPTIND''' || È una variabile della shell, che contiene l'indice del parametro posizionale del prossimo argomento da processare. Viene modificata da ''getopts'', che la usa per tenere traccia del proprio stato. Torna utile anche per poter fare uno shift dei parametri posizionali, dopo averli analizzati con ''getopts''. ||
||<:> '''OPTARG''' || Se è previsto un parametro, viene impostata al valore si quest'ultimo. Se l'opzione non prevede un parametro, è lasciato vuoto. Se l'opzione passata è sconosciuta, viene impostato al valore dell'opzione.||
||<:> '''OPTERR''' || È una variabile di bash, che può assumere il valore 1 o 0, a seconda che si desideri o meno che la shell mostri il messaggio d'errore generato automaticamente da ''getopts''. Di default è impostata ad 1 e ha senso modificarla solo nella modalità verbosa. Non è supportata in shell quali ksh93, mksh, zsh, or dash.||
La gestione del parametro '''varname''' e della variabile '''OPTARG''' cambia a seconda della modalità in cui si usa il comando ed è riassunta nella seguente tabella:
||||||'''Modalità verbosa''' ||
||<20%>opzione<
>non valida ||'''varname''' è posto uguale al carattere '?'<
>'''OPTARG''' è lasciato vuoto.||
||<20%>parametro obbligatorio<
>non fornito ||'''varname''' è posto uguale al carattere '?'<
>'''OPTARG''' è lasciato vuoto e viene stampato un messaggio d'errore.||
||||||'''Modalità silenziosa''' ||
||<20%>opzione<
>non valida ||'''varname''' è posto uguale al carattere '?'<
>'''OPTARG''' è posto uguale all'opzione non valida.||
||<20%>parametro obbligatorio<
>non fornito ||'''varname''' è posto uguale al carattere ':'<
>'''OPTARG''' è posto uguale all'opzione||
== Esempi d'uso ==
Il comando viene generalmente usato all'interno di un ciclo ''while'': a ogni iterazione, legge dalla stringa dei parametri posizionali (o da ''args'' se fornito) un'opzione e il suo eventuale parametro; se tutto è corretto, aggiorna le sue variabili interne, secondo quanto visto al punto precedente, e fornisce questi dati all'utente per la loro analisi, che viene svolta all'interno di un costrutto ''case''. Il comando restituisce un ''exit status'' uguale a 1, interrompendo il ciclo ''while'', quando incontra il primo parametro opzionale che non corrisponde a una opzione prevista.
=== Modalità verbosa ===
Lo script che segue è un esempio di utilizzo del comando nella modalità verbosa. Lo script accetta le opzioni 'a' e 'c' senza parametro e le opzioni 'b' e 'd' con un parametro. Le opzioni 'b' e 'd' non sono implementate, per simulare una situazione frequente nelle fasi iniziali di sviluppo di uno script.
{{{
#!
#!/bin/bash
while getopts "ab:cd:" option
do
case $option in
a)
echo "Opzione -$option, senza argomento"
echo "OPTIND è $OPTIND"
echo "*** *** ***"
;;
b)
echo "Opzione -$option, con argomento '"$OPTARG"'"
echo "OPTIND è $OPTIND"
echo "*** *** ***"
;;
\?)
echo "OPTIND è $OPTIND" >&2
echo "Termino" >&2
exit 1
;;
*)
echo "Opzione non ancora implementata: -$option"
echo "OPTIND è $OPTIND"
echo "*** *** ***"
;;
esac
done
shift $((OPTIND - 1))
if [[ $# -ne 0 ]]
then
echo "Rimangono da analizzare i parametri:"
for i in "$@"
do
echo "--> '$i'"
done
fi
}}}
Supponendo di aver salvato lo script con il nome `prova_getopts_verboso.sh`, alcuni esempi dell'output generato da questo script sono:
{{{
$ ./prova_getopts_verboso.sh -a
Opzione -a, senza argomento
*** *** ***
Il valore di OPTIND è 2
}}} in cui allo script è fornita solo l'opzione 'a'.
{{{
$ ./prova_getopts_verboso.sh -ab 10
Opzione -a, senza argomento
OPTIND è 1
*** *** ***
Opzione -b, con argomento '10'
OPTIND è 3
*** *** ***
}}} in cui è fornita anche l'opzione 'b' con il parametro '10'.
* L'ordine delle opzioni può essere cambiato in modo consistente con la sintassi, quindi il comando precedente equivale a:
{{{
$ ./prova_getopts_verboso.sh -b 10 -a
Opzione -b, con argomento '10'
OPTIND è 3
*** *** ***
Opzione -a, senza argomento
OPTIND è 4
*** *** ***
}}}
{{{
$ ./prova_getopts_verboso.sh -d 10 -a
Opzione non ancora implementata: -d
OPTIND è 3
*** *** ***
Opzione -a, senza argomento
OPTIND è 4
*** *** ***
}}} in cui viene passata l'opzione non implementata '-d' con il parametro '10'
* Infine, se si passa un'opzione non valida, getopts produce automaticamente un messaggio d'errore:
{{{
$ ./prova_getopts_verboso.sh -f
./prova_getopts_verboso.sh: opzione illecita -- f
OPTIND è 2
Termino
}}}
=== Modalità sileziosa ===
Lo script seguente è l'analogo del precedente, ma in modalità silenziosa:
{{{
#!
#!/usr/bin/env bash
while getopts ":ab:cd:" option;
do
case $option in
a)
echo "Opzione -$option, senza argomento"
echo "OPTIND è $OPTIND"
echo "*** *** ***"
;;
b)
echo "Opzione -$option, con argomento '"$OPTARG"'"
echo "OPTIND è $OPTIND"
echo "*** *** ***"
;;
\?)
echo "Opzione non valida: -$OPTARG" >&2
echo "OPTIND è $OPTIND" >&2
echo "Termino" >&2
exit 1
;;
: )
echo "-$OPTARG richede un parametro, che non è stato passato" >&2
echo "OPTIND è $OPTIND" >&2
echo "Termino" >&2
exit 1
;;
*)
echo "Opzione non ancora implementata: -$option"
echo "OPTIND è $OPTIND"
echo "*** *** ***"
esac
done
shift $((OPTIND -1))
if [[ $# -ne 0 ]]
then
echo "Rimangono da analizzare i parametri:"
for i in "$@"
do
echo "--> '$i'"
done
fi
}}}
Differenze dallo script precedente ci sono solo per opzioni non valide e parametri obbligatori non passati. Se lo script è stato salvato col nome `prova_getopts_silenzioso.sh`, si ha rispettivamente:
{{{
$ ./prova_getopts_silenzioso.sh -f
Opzione non valida: -f
OPTIND è 2
Termino
}}}
{{{
$ ./prova_getopts_silenzioso.sh -b
-b richede un parametro, che non è stato passato
OPTIND è 2
Termino
}}}
== Considerazioni sugli esempi d'uso ==
* '''getopts''' restituisce un ''exit status'' pari a 1 se incontra un parametro che non corrisponde a una opzione prevista. Per gli script in questi esempi, è quindi necessario scrivere per ultimi i parametri che si vogliono analizzare a valle del ciclo ''while''. Se questi sono interpretabili come opzioni, vanno separati da un doppio trattino. In realtà, è possibile una gestione più articolata di questa tipologia di parametri, che però esula dalle finalità di questa guida introduttiva e per la quale si rimanda alla [[https://forum.ubuntu-it.org/viewforum.php?f=33|sezione programmazione del forum]].
* Nella versione verbosa, il caso \?) gestisce sia un'opzione non valida sia l'assenza di un parametro obbligatorio. La stampa dell'errore è gestita direttamente dal comando '''getopts''', che continua il parsing dopo aver comunicato l'errore. Se si desidera che il programma termini la sua esecuzione in questi due casi, deve essere richiesto esplicitamente, ad esempio con il comando '''exit'''.
* Nella versione silenziosa, il caso \?) gestisce un'opzione non valida e il caso : ) l'assenza di un parametro obbligatorio.
* Il caso *) permette di gestire eventuali opzioni non ancora implementate all'interno dello script. Nei due esempi, le opzioni non ancora implementate sono 'b' e 'd'. Questa modalità risulta molto comoda nella fase iniziale di implementazione di uno script.
* L'istruzione '''shift''' successiva al ciclo ''while'' ha lo scopo di eliminare dalla stringa dei parametri posizionali quelli che sono già stati analizzati. Il parametro '''OPTIND''' assicura infatti di ottenere lo slittamento verso sinistra di tutti i parametri già letti. In questo modo, lo script è in grado di gestire successivamente anche eventuali ulteriori parametri posizionali.
* È utile ricordare che '''OPTIND''' contiene l'indice del parametro posizionale del prossimo argomento da processare e quindi non viene incrementato fino ad aver esaurito l'analisi di tutte le opzioni scritte attaccate.
= Ulteriori risorse =
* [[http://www.gnu.org/software/bash/manual/bash.html|Manuale ufficiale di Bash]]
* [[http://www.tldp.org/LDP/abs/html/|Guida avanzata di scripting Bash]]
* [[http://www.pluto.it/files/ildp/guide/abs/index.html|Guida avanzata di scripting Bash in italiano]]
## da questo punto in poi non modificare!
----
CategoryNuoviDocumenti