Come utilizzare i test condizionali a doppia parentesi in Linux
Pubblicato: 2022-01-29I test condizionali ramificano il flusso di esecuzione degli script Bash Linux in base al risultato di un'espressione logica. I test condizionali a doppia parentesi semplificano considerevolmente la sintassi, ma hanno comunque i loro trucchi.
Staffe singole e doppie
Bash fornisce il comando di test
. 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 di ritorno pari a zero. Qualsiasi cosa diversa da zero indica falso.
Il concatenamento dei comandi sulla riga di comando con 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 && eco "Sì"
test 14 -eq 15 && eco "Sì"
I test condizionali a parentesi singola imitano il comando di test
. Racchiudono l'espressione tra parentesi " [ ]
" e funzionano proprio come il comando test
. In effetti, sono lo stesso programma, creato dallo stesso codice sorgente. L'unica differenza operativa è il modo in cui la versione di test
e la versione [
gestiscono le richieste di aiuto.
Questo è dal codice sorgente:
/* Riconosce --help o --version, ma solo quando viene invocato nel file Modulo "[", quando l'ultimo argomento non è "]". Usa direttamente parsing, piuttosto che parse_long_options, per evitare di accettare abbreviazioni. POSIX consente a "[ --help" e "[ --version" di hanno il solito comportamento GNU, ma richiede "test --help" e "test --version" per uscire silenziosamente con lo stato 0. */
Possiamo vedere l'effetto di ciò chiedendo aiuto a test
e [
e controllando il codice di risposta inviato a Bash.
prova --help
eco $?
[ --aiuto
eco $?
Sia test
che [
sono incorporati nella shell , il che significa che sono inseriti direttamente in Bash. Ma esiste anche una versione binaria standalone di [
.
tipo di prova
genere [
dove si trova [
Al contrario, i test condizionali a doppia parentesi [[
e ]]
sono parole chiave . [[
e ]]
eseguono anche test logici, ma la loro sintassi è diversa. Poiché sono parole chiave, puoi utilizzare alcune funzionalità che non funzioneranno nella versione a parentesi singola.
Le parole chiave a doppia parentesi sono supportate da Bash, ma non sono disponibili in tutte le altre shell. Ad esempio, la shell Korn li supporta, ma la semplice vecchia shell, sh, no. Tutti i nostri script iniziano con la riga:
#!/bin/bash
Questo assicura che stiamo chiamando la shell Bash per eseguire lo script.
CORRELATI: Come creare ed eseguire script Bash Shell su Windows 10
Built-in e parole chiave
Possiamo usare il programma compgen
per elencare i builtin:
compgen -b | fmt -w 70
Senza eseguire il pipe dell'output tramite fmt
otterremmo un lungo elenco con ogni built-in su una propria riga. In questo caso è più conveniente vedere i builtin raggruppati in un paragrafo.
Possiamo vedere test
e [
nell'elenco, ma ]
non è elencato. Il comando [
cerca una chiusura ]
per rilevare quando ha raggiunto la fine dell'espressione, ma ]
non è un builtin separato. È solo un segnale che diamo a [
per indicare la fine dell'elenco dei parametri.
Per vedere le parole chiave, possiamo usare:
compgen -k | fmt -w 70
Le parole chiave [[
e ]]
sono entrambe nell'elenco, perché [[
è una parola chiave e ]]
è un'altra. Sono una coppia abbinata, proprio come if
e fi
, e case
ed esac
.
Quando Bash sta analizzando uno script, o una riga di comando, e rileva una parola chiave che ha una parola chiave corrispondente, chiudendo raccoglie tutto ciò che appare tra di loro e applica qualsiasi trattamento speciale supportato dalle parole chiave.
Con un built-in, ciò che segue il comando integrato 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.
Globulazione delle conchiglie
I test condizionali a doppia parentesi possono utilizzare il globbing della shell. Ciò significa che l'asterisco " *
" si espanderà per indicare "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" == *alce* ]]; poi echo "L'avviso contiene frutti di mare" altro echo "Libero da molluschi" fi
Per rendere eseguibile lo script dovremo usare il comando chmod
con l'opzione -x
(execute). Dovrai farlo su 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 dagli altri caratteri che la circondano.
./whelkie.sh
Un punto da notare è che non racchiudiamo la stringa di ricerca tra virgolette doppie. Se lo fai, il globbing non avverrà. 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 gli 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* ]]; poi echo "L'avviso contiene frutti di mare." altro echo "Libero da molluschi". fi
Salva questo script come "damme.sh" e rendilo eseguibile. Quando lo eseguiamo, l'istruzione condizionale si risolve in true e la prima clausola dell'istruzione if viene eseguita.
./damme.sh
Stringhe di citazione
Abbiamo menzionato in precedenza le stringhe di wrapping tra virgolette doppie. Se lo fai, il globbing della shell non si verificherà. Sebbene la convenzione dica che è una buona pratica, non è necessario racchiudere le variabili stringa tra virgolette quando si utilizza [[
e ]]
anche se contengono spazi. Guarda il prossimo esempio. Entrambe le variabili stringa $stringvar
e $surname
contengono spazi, ma nessuna delle due viene citata nell'istruzione condizionale.
#!/bin/bash stringvar="van Damme" cognome="van Damme" if [[ $stringvar == $cognome ]]; poi echo "I cognomi corrispondono." altro echo "I cognomi non corrispondono." fi
Salvalo in un file chiamato "cognome.sh" e rendilo eseguibile. Eseguilo usando:
./cognome.sh
Nonostante entrambe le stringhe contengano spazi, lo script riesce e l'istruzione condizionale si risolve in true. Ciò è utile quando si tratta di percorsi e nomi di directory che contengono spazi. Qui, l'opzione -d
restituisce true se la variabile contiene un nome di directory valido.
#!/bin/bash dir="/home/dave/Documents/Needs Work" se [[ -d ${dir} ]]; poi echo "Directory confermata" altro echo "Directory non trovata" fi
Se modifichi il percorso nello script per riflettere una directory sul tuo computer, salvi il testo in un file chiamato "dir.sh" e lo rendi eseguibile, puoi vedere che funziona.
./dir.sh
CORRELATI: Come lavorare con le variabili in Bash
Filename Globbing Gotchas
Un'interessante differenza tra [ ]
e [[ ]]
riguarda i nomi di file con globbing. Il modulo "*.sh" corrisponderà a tutti i file di script. L'utilizzo di parentesi singole [ ]
non riesce a meno che non sia presente un unico file di script. Trovare più di uno script genera un errore.
Ecco lo script con condizionali a parentesi singola.
#!/bin/bash se [ -a *.sh]; poi echo "Trovato un file di script" altro echo "Non ho trovato un file di script" fi
Abbiamo salvato questo testo in "script.sh" e lo abbiamo reso eseguibile. Abbiamo verificato 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 eseguito nuovamente lo script.
ls
./script.sh
Il test condizionale restituisce true e lo script non causa errori. La modifica dello script per l'utilizzo di parentesi quadre fornisce un terzo tipo di comportamento.
#!/bin/bash se [[ -a *.sh ]]; poi echo "Trovato un file di script" altro echo "Non ho trovato un file di script" 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 riesce a riconoscere alcun file di script.
L'istruzione condizionale che utilizza le doppie parentesi si risolve in true solo nell'improbabile caso in cui nella directory sia presente un file chiamato "*.sh".
./dscript.sh
AND logico e OR
Le doppie parentesi ti permettono di usare &&
e ||
come gli 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 primo=10 secondo=25 if [[ first -eq 10 && second -lt 26 ]]; poi eco "Condizione soddisfatta" altro echo "Condizione non riuscita" fi
Salva questo testo in un file chiamato "and.sh", rendilo eseguibile ed eseguilo con:
./e.sh
Lo script viene eseguito come ci aspetteremmo.
Questa volta useremo il ||
operatore. L'affermazione condizionale dovrebbe risolversi in true perché sebbene 10 non sia maggiore di 15, 25 è comunque inferiore a 26. Finché il primo confronto o il secondo confronto è vero, l'affermazione condizionale nel suo insieme si risolve in true.
Salva questo testo come "or.sh" e rendilo eseguibile.
#!/bin/bash primo=10 secondo=25 se [[ primo -gt 15 || secondo -lt 26 ]]; poi echo "Condizione soddisfatta." altro echo "Condizione non riuscita." fi
./o.sh
Regix
Le istruzioni condizionali a doppia parentesi consentono l'uso dell'operatore =~
, che applica i modelli di ricerca delle espressioni regolari in una stringa all'altra metà dell'istruzione. Se la regex è soddisfatta, l'affermazione condizionale è considerata vera. Se la regex non trova corrispondenze, l'istruzione condizionale si risolve in false.
CORRELATI: Come utilizzare le espressioni regolari (regex) su Linux
Salva questo testo in un file chiamato "regex.sh" e rendilo eseguibile.
#!/bin/bash parole = "uno due tre" WordsandNumbers="uno 1 due 2 tre 3" email="[email protected]" maschera1="[0-9]" mask2="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}" if [[ $parole =~ $maschera1 ]]; poi echo "\"$parole\" contiene cifre." altro echo "Nessuna cifra trovata in \"$parole\"." fi if [[ $ParoleeNumeri =~ $maschera1 ]]; poi echo "\"$WordsandNumbers\" contiene cifre." altro echo "Nessuna cifra trovata in \"$WordsandNumbers\"." fi se [[ $email =~ $maschera2 ]]; poi echo "\"$email\" è un indirizzo e-mail valido." altro echo "Impossibile analizzare \"$email\"." fi
Il primo set 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 espressione regolare alla variabile stringa $words
.
Il secondo set di doppie parentesi usa di nuovo la variabile stringa $mask1
come regex, ma questa volta la usa con la variabile stringa $WordsandNumbers
.
L'ultimo set di doppie parentesi utilizza 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 di "[]
" 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 di "[ ]
" 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}
" indica la corrispondenza di almeno due caratteri e al massimo quattro.
Mettendo tutto insieme, la maschera regolare verificherà se un indirizzo e-mail è 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 non riesce perché l'espressione regolare sta cercando cifre ma non ci sono cifre nel valore contenuto nella variabile stringa $words
.
La seconda istruzione condizionale ha esito positivo perché la variabile stringa $WordsandNumbers
contiene cifre.
L'istruzione condizionale finale riesce, ovvero si risolve in true, perché l'indirizzo e-mail è 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 di [[
e ]]
.
Assicurati solo che lo script chiami una shell che li supporti, come Bash.
RELAZIONATO: 15 personaggi speciali che devi conoscere per Bash