
I test condizionali ramificano il flusso di esecuzione degli script Linux Bash in base al risultato di un’espressione logica. I test condizionali a doppia parentesi semplificano notevolmente la sintassi, ma hanno ancora i loro trucchi.
Staffe singole e doppie
Bash fornisce il test comando. Ciò consente di testare le espressioni logiche. L’espressione restituirà una risposta che indica una risposta vera o falsa. Una risposta vera è indicata da un valore restituito pari a zero. Qualsiasi cosa diversa da zero indica falso.
Concatenamento di comandi sulla riga di comando con il && l’operatore utilizza questa funzione. I comandi vengono eseguiti solo se il comando precedente viene completato correttamente.
Se il test è vero, verrà stampata la parola “Sì”.
test 15 -eq 15 && echo "Yes"
test 14 -eq 15 && echo "Yes"

I test condizionali a parentesi singola imitano il test comando. Racchiudono l’espressione tra parentesi “[ ]” e operare proprio come il test comando. In effetti, sono lo stesso programma, creato dallo stesso codice sorgente. L’unica differenza operativa è come il test versione e il [ version handle help requests.
This is from the source code:
/* Recognize --help or --version, but only when invoked in the "[" form, when the last argument is not "]". Usa l'analisi diretta, piuttosto che parse_long_options, per evitare di accettare abbreviazioni. POSIX consente "[ --help" and "[ --version" to have the usual GNU behavior, but it requires "test --help" and "test --version" to exit silently with status 0. */
We can see the effect of this by asking test and [ for help and checking the response code sent to Bash.
test --help
echo $?
[ --help
echo $?

Both test and [ are shell builtins, meaning they are baked right into Bash. But there’s also a standalone binary version of [ .
type test
type [
whereis [

By contrast, the double bracket conditional tests [[ and ]] sono parole chiave. [[ and ]] eseguono anche test logici, ma la loro sintassi è diversa. Poiché sono parole chiave, puoi utilizzare alcune funzionalità pulite che non funzioneranno nella versione a parentesi singola.
Le parole chiave doppie parentesi quadre sono supportate da Bash, ma non sono disponibili in tutte le altre shell. Ad esempio, la shell Korn li supporta, ma la vecchia shell semplice, sh, no. Tutti i nostri script iniziano con la riga:
#!/bin/bash
Questo assicura che stiamo chiamando la shell Bash per eseguire lo script.
IMPARENTATO: Come creare ed eseguire script Bash Shell su Windows 10
Builtin e parole chiave
Possiamo usare il compgen programma per elencare i builtin:
compgen -b | fmt -w 70
Senza convogliare l’uscita attraverso fmt otterremmo una lunga lista con ogni builtin su una propria riga. È più conveniente in questo caso vedere i comandi incorporati raggruppati in un paragrafo.

Possiamo vedere test e [ in the list, but ] non è elencato. Il [ command looks for a closing ] per rilevare quando ha raggiunto la fine dell’espressione, ma ] non è un builtin separato. È solo un segnale che diamo a [ to indicate the end of the parameter list.
To see the keywords, we can use:
compgen -k | fmt -w 70

The [[ and ]] le parole chiave sono entrambe nell’elenco, perché [[ is a one keyword and ]] è un altro. Sono una coppia assortita, proprio come if e fi , e case e esac .
Quando Bash sta analizzando uno script o una riga di comando e rileva una parola chiave che ha una parola chiave di chiusura corrispondente, raccoglie tutto ciò che appare tra di loro e applica qualsiasi trattamento speciale supportato dalle parole chiave.
Con un builtin, ciò che segue il comando builtin gli viene passato esattamente come i parametri di qualsiasi altro programma da riga di comando. Ciò significa che l’autore dello script deve prestare particolare attenzione a cose come gli spazi nei valori variabili.
Globbing delle conchiglie
I test condizionali a doppia parentesi possono fare uso del globbing della shell. Questo significa l’asterisco “*” si espanderà per significare “qualsiasi cosa”.
Digita o copia il seguente testo in un editor e salvalo in un file chiamato “whelkie.sh”.
#!/bin/bash stringvar="Whelkie Brookes" if [[ "$stringvar" == *elk* ]]; then echo "Warning contains seafood" else echo "Free from molluscs" fi
Per rendere eseguibile lo script dovremo usare il chmod comando con il -x (esegui) opzione. Dovrai farlo per tutti gli script in questo articolo se vuoi provarli.
chmod +x whelkie.sh

Quando eseguiamo lo script vediamo che la stringa “elk” è stata trovata nella stringa “Whelkie”, indipendentemente da quali altri caratteri la circondano.
./whelkie.sh

Un punto da notare è che non racchiudiamo la stringa di ricerca tra virgolette. Se lo fai, il globbing non accadrà. La stringa di ricerca verrà trattata letteralmente.
Sono consentite altre forme di shell globbing. Il punto interrogativo”?” corrisponderà a singoli caratteri e le singole parentesi quadre vengono utilizzate per indicare intervalli di caratteri. Ad esempio, se non sai quale custodia utilizzare, puoi coprire entrambe le eventualità con un intervallo.
#!/bin/bash stringvar="Jean-Claude van Clam" if [[ "$stringvar" == *[cC]lam* ]]; then echo "Warning contains seafood." else echo "Free from molluscs." fi
Salva questo script come “damme.sh” e rendilo eseguibile. Quando lo eseguiamo, l’istruzione condizionale si risolve in true e viene eseguita la prima clausola dell’istruzione if.
./damme.sh

Citando le stringhe
Abbiamo menzionato l’avvolgimento delle stringhe tra virgolette in precedenza. Se lo fai, il globbing della shell non si verificherà. Anche se la convenzione dice che è una buona pratica, tu no bisogno avvolgere le variabili stringa tra virgolette quando si utilizza [[ and ]]anche se contengono spazi. Guarda il prossimo esempio. entrambi i $stringvar e $surname le variabili stringa contengono spazi, ma nessuna delle due è citata nell’istruzione condizionale.
#!/bin/bash stringvar="van Damme" surname="van Damme" if [[ $stringvar == $surname ]]; then echo "Surnames match." else echo "Surnames don't match." fi
Salvalo in un file chiamato “surname.sh” e rendilo eseguibile. Eseguilo usando:
./surname.sh

Nonostante entrambe le stringhe contengano spazi, lo script ha esito positivo e l’istruzione condizionale si risolve in true. Questo è utile quando si tratta di percorsi e nomi di directory che contengono spazi. qui, il -d l’opzione restituisce true se la variabile contiene un nome di directory valido.
#!/bin/bash
dir="/home/dave/Documents/Needs Work"
if [[ -d ${dir} ]];
then
echo "Directory confirmed"
else
echo "Directory not found"
fi
Se cambi il percorso nello script per riflettere una directory sul tuo computer, salva il testo in un file chiamato “dir.sh” e rendilo eseguibile, puoi vedere che funziona.
./dir.sh

IMPARENTATO: Come lavorare con le variabili in Bash
Filename Globbing Gotchas
Un’interessante differenza tra [ ] e [[ ]] si riferisce ai nomi di file con globbing al loro interno. Il modulo “*.sh” corrisponderà a tutti i file di script. Utilizzo di parentesi singole [ ] non riesce a meno che non sia presente un singolo file di script. Trovare più di uno script genera un errore.
Ecco lo script con i condizionali a parentesi singola.
#!/bin/bash if [ -a *.sh ]; then echo "Found a script file" else echo "Didn't find a script file" fi
Abbiamo salvato questo testo in “script.sh” e lo abbiamo reso eseguibile. Abbiamo controllato quanti script c’erano nella directory, quindi abbiamo eseguito lo script.
ls
./script.sh

Bash genera un errore. Abbiamo rimosso tutti i file di script tranne uno ed abbiamo eseguito nuovamente lo script.
ls
./script.sh

Il test condizionale restituisce true e lo script non causa errori. La modifica dello script per utilizzare le doppie parentesi fornisce un terzo tipo di comportamento.
#!/bin/bash if [[ -a *.sh ]]; then echo "Found a script file" else echo "Didn't find a script file" fi
Lo abbiamo salvato in un file chiamato “dscript.sh” e lo abbiamo reso eseguibile. L’esecuzione di questo script in una directory con molti script non genera un errore, ma lo script non riconosce alcun file di script.
L’istruzione condizionale che utilizza le doppie parentesi si risolve in true solo nel caso improbabile che tu abbia un file effettivamente chiamato “*.sh” nella directory.
./dscript.sh

AND e OR logici
Le doppie parentesi ti permettono di usare && e || come operatori logici AND e OR.
Questo script dovrebbe risolvere l’istruzione condizionale in true perché 10 è uguale a 10 e 25 è inferiore a 26.
#!/bin/bash first=10 second=25 if [[ first -eq 10 && second -lt 26 ]]; then echo "Condition met" else echo "Condition failed" fi
Salva questo testo in un file chiamato “and.sh”, rendilo eseguibile ed eseguilo con:
./and.sh

Lo script viene eseguito come ci aspetteremmo.
Questa volta useremo il || operatore. L’istruzione condizionale dovrebbe risolversi in vero perché sebbene 10 non sia maggiore di 15, 25 è ancora minore di 26. Finché il primo confronto o il secondo confronto è vero, l’affermazione condizionale nel suo insieme si risolve in vero.
Salva questo testo come “or.sh” e rendilo eseguibile.
#!/bin/bash first=10 second=25 if [[ first -gt 15 || second -lt 26 ]]; then echo "Condition met." else echo "Condition failed." fi
./or.sh

regex
Le dichiarazioni condizionali tra parentesi doppie consentono l’uso di =~ operatore, che applica i modelli di ricerca regex in una stringa all’altra metà dell’istruzione. Se la regex è soddisfatta, l’istruzione condizionale è considerata vera. Se l’espressione regolare non trova corrispondenze, l’istruzione condizionale si risolve in false.
IMPARENTATO: Come usare le espressioni regolari (regex) su Linux
Salva questo testo in un file chiamato “regex.sh” e rendilo eseguibile.
#!/bin/bash
words="one two three"
WordsandNumbers="one 1 two 2 three 3"
email="dave@fabricateddomain.co.uk"
mask1="[0-9]"
mask2="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}"
if [[ $words =~ $mask1 ]];
then
echo ""$words" contains digits."
else
echo "No digits found in "$words"."
fi
if [[ $WordsandNumbers =~ $mask1 ]];
then
echo ""$WordsandNumbers" contains digits."
else
echo "No digits found in "$WordsandNumbers"."
fi
if [[ $email =~ $mask2 ]];
then
echo ""$email" is a valid e-mail address."
else
echo "Couldn't parse "$email"."
fi
La prima serie di doppie parentesi usa la variabile stringa $mask1 come regex. Questo contiene il modello per tutte le cifre nell’intervallo da zero a nove. Applica questa regex al $words variabile stringa.
La seconda serie di doppie parentesi usa ancora la variabile stringa $mask1 come l’espressione regolare, ma questa volta lo usa con il $WordsandNumbers variabile stringa.
L’ultimo set di doppie parentesi usa una maschera regex più complessa nella variabile stringa $mask2 .
-
[A-Za-z0-9._%+-]+: corrisponde a qualsiasi carattere che sia una lettera maiuscola o minuscola, o qualsiasi cifra da zero a nove, o un punto, un trattino basso, un segno di percentuale o un segno più o meno. Il “
+” al di fuori del “[]” significa ripetere quelle corrispondenze per tutti i caratteri che trova. - @: Corrisponde solo al carattere “@”.
-
[A-Za-z0-9.-]+: corrisponde a qualsiasi carattere che sia una lettera maiuscola o minuscola, o qualsiasi cifra da zero a nove, o un punto o un trattino. Il “
+” al di fuori del “[ ]” significa ripetere quelle corrispondenze per tutti i caratteri che trova. - .: corrisponde a “.” solo carattere.
-
[A-Za-z]{2,4}: corrisponde a qualsiasi lettera maiuscola o minuscola. Il “
{2,4}” significa corrispondere ad almeno due caratteri e al massimo a quattro.
Mettendo tutto insieme, la maschera regex verificherà se un indirizzo email è formato correttamente.
Salva il testo dello script in un file chiamato “regex.sh” e rendilo eseguibile. Quando eseguiamo lo script otteniamo questo output.
./regex.sh

La prima istruzione condizionale fallisce perché l’espressione regolare sta cercando cifre ma non ci sono cifre nel valore contenuto nel $words variabile stringa.
La seconda istruzione condizionale ha successo perché il $WordsandNumbers variabile stringa contiene cifre.
L’istruzione condizionale finale ha esito positivo, ovvero si risolve in true, perché l’indirizzo di posta elettronica è formattato correttamente.
Solo una condizione
I test condizionali a doppia parentesi offrono flessibilità e leggibilità ai tuoi script. Il solo fatto di essere in grado di utilizzare le espressioni regolari nei test condizionali giustifica l’apprendimento dell’uso [[ and ]].
Assicurati solo che lo script chiami una shell che li supporti, come Bash.
IMPARENTATO: 15 caratteri speciali che devi conoscere per Bash
