Come utilizzare i test condizionali a doppia parentesi in Linux

fatmawati achmad zaenuri/Shutterstock.com

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"

Semplici esempi del comando Bash test

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. */
Advertisement

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 $?

Using --help on test and [

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 [

Finding the different types of [ and test commands

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
Annuncio pubblicitario

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.

Elencare i builtin di Bash

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

Listing the Bash keywords

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”.

Annuncio pubblicitario

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

Usare chmod per rendere eseguibile uno script

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

./whelkie.sh

Esecuzione dello script 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

Esecuzione dello script 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
Annuncio pubblicitario

Salvalo in un file chiamato “surname.sh” e rendilo eseguibile. Eseguilo usando:

./surname.sh

Esecuzione dello script cognome.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

Esecuzione dello script 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

Esecuzione dello script script.sh

Annuncio pubblicitario

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

ls
./script.sh

Esecuzione dello script script.sh con un singolo script nella directory

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

Esecuzione dello script 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
Annuncio pubblicitario

Salva questo testo in un file chiamato “and.sh”, rendilo eseguibile ed eseguilo con:

./and.sh

Esecuzione dello script 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

Esecuzione dello script 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.

Annuncio pubblicitario

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

Esecuzione dello script 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.

Annuncio pubblicitario

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

Articoli correlati

Ultimi articoli