
Le istruzioni case Bash sono potenti ma facili da scrivere. Quando rivisiti un vecchio script Linux sarai felice di aver usato a case dichiarazione invece di una lunga if-then-else dichiarazione.
Il caso Dichiarazione
La maggior parte dei linguaggi di programmazione ha la propria versione di a switch o case dichiarazione. Questi dirigono il flusso di esecuzione del programma in base al valore di una variabile. Tipicamente, esiste un ramo di esecuzione definito per ciascuno dei possibili valori attesi della variabile e un catch-all or predefinito ramo per tutti gli altri valori.
La funzionalità logica è simile a una lunga sequenza di if-then dichiarazioni con an else dichiarazione che cattura tutto ciò che non è stato precedentemente gestito da uno dei if dichiarazioni.
L’implementazione di Bash di case cerca di abbinare un espressione con una delle clausole. Lo fa guardando ogni clausola, a sua volta, cercando di trovare una corrispondenza modello. I pattern nelle clausole sono stringhe, ma, controintuitivamente, ciò non significa che non possiamo usare valori numerici come espressione.
Il caso generico
La forma generica di case l’affermazione è questa:
case expression in pattern-1) statement ;; pattern-2) statement ;; . . . pattern-N) statement ;; *) statement ;; esac
- UN
casel’istruzione deve iniziare concaseparola chiave e termina conesacparola chiave. - L’espressione viene valutata e confrontata con i modelli in ciascuno clausola fino a quando non viene trovata una corrispondenza.
- L’istruzione o le istruzioni nella clausola di corrispondenza vengono eseguite.
- Un doppio punto e virgola”
;;” viene utilizzato per terminare una clausola. - Se viene trovato un modello e le istruzioni in quella clausola vengono eseguite, tutti gli altri modelli vengono ignorati.
- Non c’è limite al numero di clausole.
- Un asterisco”
*” denota il modello predefinito. Se un’espressione non corrisponde a nessuno degli altri modelli nelcaseistruzione viene eseguita la clausola predefinita.
Un semplice esempio
Questo script ci dice gli orari di apertura di un negozio immaginario. utilizza il date comando con il +"%a" stringa di formato per ottenere il nome del giorno abbreviato. Questo è memorizzato nel DayName variabile.
#!/bin/bash
DayName=$(date +"%a")
echo "Opening hours for $DayName"
case $DayName in
Mon)
echo "09:00 - 17:30"
;;
Tue)
echo "09:00 - 17:30"
;;
Wed)
echo "09:00 - 12:30"
;;
Thu)
echo "09:00 - 17:30"
;;
Fri)
echo "09:00 - 16:00"
;;
Sat)
echo "09:30 - 16:00"
;;
Sun)
echo "Closed all day"
;;
*)
;;
esac
Copia quel testo in un editor e salvalo come file chiamato “open.sh”.
Dovremo usare il chmod comando per renderlo eseguibile. Dovrai farlo per tutti gli script che crei mentre lavori in questo articolo.
chmod +x open.sh

Ora possiamo eseguire il nostro script.
./open.sh

Il giorno in cui è stato scattato lo screenshot è venerdì. Ciò significa che DayName variabile contiene la stringa “Ven”. Questo è abbinato al modello “Fri” della clausola “Fri)”.
Nota che i modelli nelle clausole non devono essere racchiusi tra virgolette, ma non fa alcun male se lo sono. Tuttavia, tu dovere usa le virgolette se il modello contiene spazi.
La clausola predefinita è stata lasciata vuota. Tutto ciò che non corrisponde a una delle clausole precedenti viene ignorato.
Quello script funziona ed è facile da leggere, ma è prolisso e ripetitivo. Possiamo abbreviare quel tipo di case dichiarazione abbastanza facilmente.
IMPARENTATO: Come usare il comando chmod su Linux
Utilizzo di più pattern in una clausola
Una caratteristica davvero carina di case affermazioni è che puoi utilizzare più modelli in ogni clausola. Se l’espressione corrisponde a uno di questi modelli, vengono eseguite le istruzioni in quella clausola.
Ecco uno script che ti dice quanti giorni ci sono in un mese. Possono esserci solo tre risposte: 30 giorni, 31 giorni o 28 o 29 giorni per febbraio. Quindi, anche se ci sono 12 mesi ci servono solo tre clausole.
In questo script, all’utente viene richiesto il nome di un mese. Per rendere la corrispondenza tra maiuscole e minuscole insensibile usiamo il shopt comando con il -s nocasematch opzione. Non importa se l’input contiene lettere maiuscole, minuscole o una combinazione delle due.
#!/bin/bash
shopt -s nocasematch
echo "Enter name of a month"
read month
case $month in
February)
echo "28/29 days in $month"
;;
April | June | September | November)
echo "30 days in $month"
;;
January | March | May | July | August | October | December)
echo "31 days in $month"
;;
*)
echo "Unknown month: $month"
;;
esac
Febbraio riceve una clausola a sé e tutti gli altri mesi condividono due clausole a seconda che abbiano 30 o 31 giorni. Le clausole multi-pattern utilizzano il simbolo della barra verticale “|” come separatore. Il caso predefinito cattura i mesi scritti male.
Lo abbiamo salvato in un file chiamato “month.sh” e lo abbiamo reso eseguibile.
chmod +x month.sh
Eseguiremo lo script più volte e dimostreremo che non importa se usiamo maiuscole o minuscole.
./month.sh

Poiché abbiamo detto allo script di ignorare le differenze tra maiuscole e minuscole, qualsiasi nome del mese digitato correttamente viene gestito da una delle tre clausole principali. I mesi scritti male vengono presi dalla clausola predefinita.
Utilizzo delle cifre nel caso Dichiarazioni
Possiamo anche usare cifre o variabili numeriche come espressione. Questo script chiede all’utente di inserire un numero nell’intervallo 1..3. Per chiarire che i modelli in ogni clausola sono stringhe, sono stati racchiusi tra virgolette. Nonostante ciò, lo script abbina ancora l’input dell’utente alla clausola appropriata.
#!/bin/bash
echo "Enter 1, 2, or 3: "
read Number
case $Number in
"1")
echo "Clause 1 matched"
;;
"2")
echo "Clause 2 matched"
;;
"3")
echo "Clause 3 matched"
;;
*)
echo "Default clause matched"
;;
esac
Salva questo in un file chiamato “number.sh”, rendilo eseguibile, quindi eseguilo:
./number.sh

Utilizzo delle istruzioni case nei cicli for
UN case l’istruzione cerca di far corrispondere il modello a una singola espressione. Se hai molte espressioni da elaborare, puoi mettere il case dichiarazione all’interno di a for ciclo continuo.
Questo script esegue il ls comando per ottenere un elenco di file. Nel for loop, il file globbing, simile ma diverso dalle espressioni regolari, viene applicato a ciascun file a turno per estrarre l’estensione del file. Questo è memorizzato nel Extension variabile stringa.
Il case l’istruzione usa il Extension variabile come l’espressione che cerca di far corrispondere a una clausola.
#!/bin/bash
for File in $(ls)
do
# extract the file extension
Extension=${File##*.}
case "$Extension" in
sh)
echo " Shell script: $File"
;;
md)
echo " Markdown file: $File"
;;
png)
echo "PNG image file: $File"
;;
*)
echo "Unknown: $File"
;;
esac
done
Salva questo testo in un file chiamato “filetype.sh”, rendilo eseguibile, quindi eseguilo usando:
./filetype.sh

Il nostro script di identificazione del tipo di file minimalista funziona.
IMPARENTATO: Come usare “Here Documents” in Bash su Linux
Gestione dei codici di uscita con dichiarazioni del caso
Un programma ben educato invierà un codice di uscita alla shell quando termina. Lo schema convenzionale utilizza un valore del codice di uscita pari a zero per indicare un’esecuzione senza problemi e valori di uno o più per indicare diversi tipi di errore.
Molti programmi usano solo zero e uno. Raggruppare tutte le condizioni di errore in un unico codice di uscita rende più difficile l’identificazione dei problemi, ma è una pratica comune.
Abbiamo creato un piccolo programma chiamato “go-geek” che restituirebbe casualmente codici di uscita pari a zero o uno. Questo prossimo script chiama go-geek. Acquisisce il codice di uscita utilizzando il $? variabile di shell e la usa come espressione per il case dichiarazione.
Uno script del mondo reale eseguirebbe l’elaborazione appropriata in base al successo o al fallimento del comando che ha generato il codice di uscita.
#!/bin/bash
go-geek
case $? in
"0")
echo "Response was: Success"
echo "Do appropriate processing in here"
;;
"1")
echo "Response was: Error"
echo "Do appropriate error handling in here"
;;
*)
echo "Unrecognised response: $?"
;;
esac
Salvalo in uno script chiamato “return-code.sh” e rendilo eseguibile. Dovrai sostituire qualche altro comando per il nostro go-geek comando. Potresti provare a cd in una directory che non esiste per ottenere un codice di uscita di uno, quindi modificare lo script in cd in una directory accessibile per ottenere un codice di uscita pari a zero.
L’esecuzione dello script alcune volte mostra i diversi codici di uscita correttamente identificati dal case dichiarazione.
./return-code.sh

La leggibilità aiuta la manutenibilità
Tornare ai vecchi script di Bash e capire come fanno quello che fanno, specialmente se sono stati scritti da qualcun altro, è impegnativo. Modificare la funzionalità dei vecchi script è ancora più difficile.
Il case L’istruzione ti offre una logica di ramificazione con una sintassi chiara e semplice. Questa è una vittoria per tutti.
IMPARENTATO: Come installare e utilizzare Linux Bash Shell su Windows 10
