<Precedenti | Contenuti | Succ.>
Combinazione di espressioni
È anche possibile combinare le espressioni per creare valutazioni più complesse. Le espressioni vengono combinate utilizzando operatori logici. Li abbiamo visti nel Capitolo 17, quando abbiamo appreso Find comando. Ci sono tre operazioni logiche per test e [[]]Sono AND, OR e NOT. test e [[]] utilizzare operatori diversi per rappresentare queste operazioni:
Tabella 27-4: Operatori logici
Funzionamento test [[ ]] e (( ))
Funzionamento test [[ ]] e (( ))
E -UN &&
OR -o ||
NON ! !
Ecco un esempio di operazione AND. Lo script seguente determina se un numero intero rientra in un intervallo di valori:
#! / Bin / bash
# test-integer3: determina se un intero è compreso in un
# intervallo di valori specificato.
MIN_VAL=1 MAX_VAL=100
INT=50
#! / Bin / bash
# test-integer3: determina se un intero è compreso in un
# intervallo di valori specificato.
MIN_VAL=1 MAX_VAL=100
INT=50
se [[ "$INT" =~ ^-?[0-9]+$ ]]; allora
se [[ INT -ge MIN_VAL && INT -le MAX_VAL ]]; allora echo "$INT è compreso tra $MIN_VAL e $MAX_VAL."
altro
echo "$INT è fuori intervallo."
per altro
echo "INT non è un numero intero." >&2 uscita 1
fi
se [[ "$INT" =~ ^-?[0-9]+$ ]]; allora
se [[ INT -ge MIN_VAL && INT -le MAX_VAL ]]; allora echo "$INT è compreso tra $MIN_VAL e $MAX_VAL."
altro
echo "$INT è fuori intervallo."
per altro
echo "INT non è un numero intero." >&2 uscita 1
fi
In questo script, determiniamo se il valore dell'intero INT si trova tra i valori di MIN_VAL e VALORE_MAXCiò avviene tramite un singolo utilizzo di [[]], che include due espressioni separate da && operatore. Avremmo potuto anche codificarlo usando test:
if [ $INT -ge $MIN_VAL -a $INT -le $MAX_VAL ]; quindi echo "$INT è compreso tra $MIN_VAL e $MAX_VAL."
altro
echo "$INT è fuori intervallo."
fi
if [ $INT -ge $MIN_VAL -a $INT -le $MAX_VAL ]; quindi echo "$INT è compreso tra $MIN_VAL e $MAX_VAL."
altro
echo "$INT è fuori intervallo."
fi
. ! L'operatore di negazione inverte il risultato di un'espressione. Restituisce true se un'espressione è falsa e restituisce false se un'espressione è vera. Nello script seguente, modifichiamo la logica della nostra valutazione per trovare i valori di INT che sono al di fuori dell'intervallo specificato:
#! / Bin / bash
# test-integer4: determina se un intero è al di fuori di un
# intervallo di valori specificato.
MIN_VAL=1 MAX_VAL=100
INT=50
se [[ "$INT" =~ ^-?[0-9]+$ ]]; allora
se [[ ! (INT -ge MIN_VAL && INT -le MAX_VAL) ]]; allora echo "$INT è al di fuori di $MIN_VAL rispetto a $MAX_VAL."
altro
echo "$INT è nell'intervallo."
#! / Bin / bash
# test-integer4: determina se un intero è al di fuori di un
# intervallo di valori specificato.
MIN_VAL=1 MAX_VAL=100
INT=50
se [[ "$INT" =~ ^-?[0-9]+$ ]]; allora
se [[ ! (INT -ge MIN_VAL && INT -le MAX_VAL) ]]; allora echo "$INT è al di fuori di $MIN_VAL rispetto a $MAX_VAL."
altro
echo "$INT è nell'intervallo."
echo "INT non è un numero intero." >&2 uscita 1
fi
echo "INT non è un numero intero." >&2 uscita 1
fi
Includiamo anche le parentesi attorno all'espressione, per il raggruppamento. Se queste non fossero incluse, la negazione si applicherebbe solo alla prima espressione e non alla combinazione delle due. Codificando questo con test si farebbe in questo modo:
if [ ! \( $INT -ge $MIN_VAL -a $INT -le $MAX_VAL \) ]; then echo "$INT è compreso tra $MIN_VAL e $MAX_VAL."
altro
echo "$INT è nell'intervallo."
fi
if [ ! \( $INT -ge $MIN_VAL -a $INT -le $MAX_VAL \) ]; then echo "$INT è compreso tra $MIN_VAL e $MAX_VAL."
altro
echo "$INT è nell'intervallo."
fi
Poiché tutte le espressioni e gli operatori utilizzati da test sono trattati come argomenti di comando dalla shell (a differenza di [[]] e (( )) ), caratteri che hanno un significato speciale per bash, come <, >, (e ), devono essere racchiusi tra virgolette o preceduti da escape.
Visto che test e [[]] fanno più o meno la stessa cosa, quale è preferibile? test è tradizionale (e parte di POSIX), mentre [[]] è specifico per bashÈ importante sapere come usare test, poiché è molto utilizzato, ma [[]] è chiaramente più utile e più facile da codificare, quindi è preferito per gli script moderni.
La portabilità è il folletto delle piccole menti
Se parli con i "veri" utenti Unix, scopri subito che molti di loro non amano molto Linux. Lo considerano impuro e sporco. Uno dei principi degli utenti Unix è che tutto dovrebbe essere "portabile". Ciò significa che qualsiasi script tu scriva dovrebbe poter essere eseguito, senza modifiche, su qualsiasi sistema simile a Unix.
Gli utenti Unix hanno buone ragioni per crederlo. Avendo visto cosa hanno fatto le estensioni proprietarie di comandi e shell al mondo Unix prima di POSIX, sono naturalmente diffidenti riguardo all'effetto di Linux sul loro amato sistema operativo.
Ma la portabilità ha un grave svantaggio. Impedisce il progresso. Richiede che le cose vengano sempre fatte utilizzando tecniche di "minimo comune denominatore". Nel caso della programmazione shell, significa rendere tutto compatibile con sh, la shell Bourne originale.
Questo svantaggio è la scusa che i fornitori di software proprietario usano per giustificare le loro estensioni proprietarie, solo che le chiamano "innovazioni". In realtà sono solo dispositivi di lock-in per i loro clienti.
Gli strumenti GNU, come bash, non hanno tali restrizioni. Incoraggiano la portabilità supportando gli standard ed essendo universalmente disponibili. È possibile installare bash e gli altri strumenti GNU su quasi tutti i tipi di sistema, anche Windows, senza costi. Quindi sentiti libero di usare tutte le funzionalità di bash. È veramente portatile.