Capitolo 25. Costrutti lista
I costrutti "lista and" e "lista
or" rappresentano un mezzo per elaborare consecutivamente un
elenco di comandi. I costrutti lista possono sostituire efficacemente
complessi enunciati if/then annidati
nonché l'enunciato case.
Concatenare comandi
- lista and
comando-1 && comando-2 && comando-3 && ... comando-n |
Ogni comando che a turno deve essere eseguito si accerta
che quello precedente abbia restituito come valore di
ritorno true (zero). Alla prima
restituzione di false (non-zero),
la serie dei comandi termina (il primo comando che ha
restituito false è
l'ultimo che è stato eseguito).Esempio 25-1. Usare una lista and per verificare
gli argomenti da riga di comando
#!/bin/bash
# "lista and"
if [ ! -z "$1" ] && echo "Argomento nr.1 = $1" && [ ! -z "$2" ] &&\
echo "Argomento nr.2 = $2"
then
echo "Allo script sono stati passati almeno 2 argomenti."
# Tutti i comandi della serie hanno restituito true.
else
echo "Allo script sono stati passati meno di 2 argomenti."
# Almeno uno dei comandi ha restituito false.
fi
# Notate che "if [ ! -z $1 ]" funziona, ma il suo supposto equivalente,
# if [ -n $1 ] no.
# Comunque, l'uso del quoting risolve il problema.
# if [ -n "$1" ] funziona.
# State attenti!
# In una verifica, è sempre meglio usare le variabili con il QUOTING.
# Questo svolge la stesso compito usando solamente enunciati if/then.
if [ ! -z "$1" ]
then
echo "Argomento nr.1 = $1"
fi
if [ ! -z "$2" ]
then
echo "Argomento nr.2 = $2"
echo "Allo script sono stati passati almeno 2 argomenti."
else
echo "Allo script sono stati passati meno di 2 argomenti."
fi
# È più lungo e meno elegante di una "lista and".
exit 0 |
Esempio 25-2. Un'altra verifica di argomenti da riga di comando utilizzando
una lista and
#!/bin/bash
ARG=1 # Numero degli argomenti attesi.
E_ERR_ARG=65 # Valore d'uscita se il numero di argomenti passati è errato.
test $# -ne $ARG && echo "Utilizzo: `basename $0` $ARG \
argomento/i" && exit $E_ERR_ARG
# Se la prima condizione dà come risultato vero (numero errato di argomenti
#+ passati allo script), allora vengono eseguiti i comandi successivi
#+ e lo script termina.
# La riga seguente verrà eseguita solo se fallisce la verifica precedente.
echo "Allo script è stato passato un numero corretto di argomenti."
exit 0
# Per verificare il valore d'uscita, eseguite "echo $?" dopo che lo script
#+ è terminato. |
Naturalmente, una lista and può anche
essere usata per impostare le variabili ad un
valore predefinito.
arg1=$@ && [ -z "$arg1" ] && arg1=DEFAULT
# Imposta $arg1 agli argomenti passati da riga di comando,
#+ se ce ne sono.
# Ma . . . la impostata a DEFAULT se, da riga di comando, non è
#+ stato passato niente. |
- lista or
comando-1 || comando-2 || comando-3 || ... comando-n |
Ogni comando che a turno deve essere eseguito si accerta che quello
precedente abbia restituito false. Alla
prima restituzione di true, la serie dei
comandi termina (il primo comando che ha restituito
true è l'ultimo che
è stato eseguito). Ovviamente è l'inverso
della "lista and".Esempio 25-3. Utilizzare la lista or in
combinazione con una lista and
#!/bin/bash
# delete.sh, utility di cancellazione di file non molto intelligente.
# Utilizzo: delete nomefile
E_ERR_ARG=65
if [ -z "$1" ]
then
echo "Utilizzo: `basename $0` nomefile"
exit $E_ERR_ARG # Nessun argomento? Abbandono.
else
file=$1 # Imposta il nome del file.
fi
[ ! -f "$file" ] && echo "File \"$file\" non trovato. \
Mi rifiuto, in modo vile, di cancellare un file inesistente."
# LISTA AND, fornisce il messaggio d'errore se il file non è presente.
# Notate il messaggio di echo che continua alla riga successiva per mezzo del
#+ carattere di escape.
[ ! -f "$file" ] || (rm -f $file; echo "File \"$file\" cancellato.")
# LISTA OR, per cancellare il file se presente.
# Notate l'inversione logica precedente.
# La LISTA AND viene eseguita se il risultato è true, la LISTA OR se è false.
exit 0 |
| Se il primo comando di una "lista
or" restituisce true,
esso verrà eseguito comunque
. |
# ==> Questi frammenti di codice, presi dallo script/etc/rc.d/init.d/single
#+==> di Miquel van Smoorenburg, illustrano l'impiego delle liste "and" e "or".
# ==> I commenti con la "freccia" sono stati aggiunti dall'autore del libro.
[ -x /usr/bin/clear ] && /usr/bin/clear
# ==> Se /usr/bin/clear esiste, allora viene invocato.
# ==> Verificare l'esistenza di un comando prima che venga eseguito
#+==> evita messaggi d'errore e i conseguenti avvertimenti.
# ==> . . .
# If they want to run something in single user mode, might as well run it...
for i in /etc/rc1.d/S[0-9][0-9]* ; do
# Check if the script is there.
[ -x "$i" ] || continue
# ==> Se il corrispondente file in $PWD *non* viene trovato,
#+==> allora "continua" saltando all'inizio del ciclo.
# Reject backup files and files generated by rpm.
case "$1" in
*.rpmsave|*.rpmorig|*.rpmnew|*~|*.orig)
continue;;
esac
[ "$i" = "/etc/rc1.d/S00single" ] && continue
# ==> Imposta il nome dello script, ma non lo esegue ancora.
$i start
done
# ==> . . . |
| L'exit
status di una lista and o di una
lista or corrisponde all'exit status
dell'ultimo comando eseguito. |
Sono possibili ingegnose combinazioni di liste
"and" e "or" , ma la loro logica
potrebbe facilmente diventare aggrovigliata e richiedere un
debugging approfondito.
false && true || echo false # false
# Stesso risultato di
( false && true ) || echo false # false
# Ma *non*
false && ( true || echo false ) # (non viene visualizzato niente)
# Notate i raggruppamenti e la valutazione degli enunciati da sinistra a destra
#+ perché gli operatori logici "&&" e "||" hanno la stessa priorità.
# È meglio evitare tali complessità, a meno che non sappiate cosa state facendo
# Grazie, S.C. |
Vedi Esempio A-7 e
Esempio 7-4 per un'illustrazione dell'uso di
una lista and / or per la verifica di
variabili.