Comment utiliser les tests conditionnels à double crochet sous Linux
Les tests conditionnels ramifient le flux d’exécution des scripts Linux Bash en fonction du résultat d’une expression logique. Les tests conditionnels à double crochet simplifient considérablement la syntaxe, mais ont toujours leurs propres pièges.
Sommaire
Supports simples et doubles
Bash fournit le test
commander. Cela vous permet de tester des expressions logiques. L’expression renverra une réponse qui indique une réponse vraie ou fausse. Une vraie réponse est indiquée par une valeur de retour de zéro. Tout autre que zéro indique faux.
Enchaîner les commandes sur la ligne de commande avec le &&
l’opérateur utilise cette fonction. Les commandes ne sont exécutées que si la commande précédente se termine avec succès.
Si le test est vrai, le mot « Oui » sera imprimé.
test 15 -eq 15 && echo "Yes"
test 14 -eq 15 && echo "Yes"
Les tests conditionnels à crochet unique imitent le test
commander. Ils mettent l’expression entre parenthèses « [ ]
» et fonctionnent comme le test
commander. En fait, il s’agit du même programme, créé à partir du même code source. La seule différence opérationnelle est la façon dont le test
version et le [
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 "]". Utilisez l'analyse directe, plutôt que parse_long_options, pour éviter d'accepter les abréviations. POSIX permet "[ --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 ]]
sont mots clés. [[
and ]]
effectuent également des tests logiques, mais leur syntaxe est différente. Comme ce sont des mots-clés, vous pouvez utiliser des fonctionnalités intéressantes qui ne fonctionneront pas dans la version à support unique.
Les mots-clés à double crochet sont pris en charge par Bash, mais ils ne sont pas disponibles dans tous les autres shells. Par exemple, le shell Korn les prend en charge, mais pas l’ancien shell simple, sh. Tous nos scripts commencent par la ligne :
#!/bin/bash
Cela garantit que nous appelons le shell Bash pour exécuter le script.
EN RELATION: Comment créer et exécuter des scripts Bash Shell sur Windows 10
Intégrés et mots-clés
Nous pouvons utiliser le compgen
programme pour lister les commandes intégrées :
compgen -b | fmt -w 70
Sans canaliser la sortie à travers fmt
nous obtiendrions une longue liste avec chaque fonction intégrée sur sa propre ligne. Il est plus pratique dans ce cas de voir les éléments intégrés regroupés dans un paragraphe.
Nous pouvons voir test
et [
in the list, but ]
n’est pas répertorié. le [
command looks for a closing ]
pour détecter quand il a atteint la fin de l’expression, mais ]
n’est pas une fonction intégrée distincte. C’est juste un signal que nous donnons à [
to indicate the end of the parameter list.
To see the keywords, we can use:
compgen -k | fmt -w 70
The [[
and ]]
les mots-clés sont tous les deux dans la liste, car [[
is a one keyword and ]]
en est un autre. Ils sont une paire assortie, tout comme if
et fi
, et case
et esac
.
Lorsque Bash analyse un script (ou une ligne de commande) et détecte un mot-clé qui a un mot-clé de fermeture correspondant, il rassemble tout ce qui apparaît entre eux et applique le traitement spécial pris en charge par les mots-clés.
Avec une commande intégrée, ce qui suit la commande intégrée lui est transmis exactement comme les paramètres de tout autre programme en ligne de commande. Cela signifie que l’auteur du script doit faire particulièrement attention à des éléments tels que les espaces dans les valeurs des variables.
Globbing des coquillages
Les tests conditionnels à double crochet peuvent utiliser le shell globbing. Cela signifie l’astérisque « *
» se développera pour signifier » n’importe quoi « .
Tapez ou copiez le texte suivant dans un éditeur et enregistrez-le dans un fichier appelé « whelkie.sh ».
#!/bin/bash stringvar="Whelkie Brookes" if [[ "$stringvar" == *elk* ]]; then echo "Warning contains seafood" else echo "Free from molluscs" fi
Pour rendre le script exécutable, nous aurons besoin d’utiliser le chmod
commande avec le -x
option (exécuter). Vous devrez le faire pour tous les scripts de cet article si vous voulez les essayer.
chmod +x whelkie.sh
Lorsque nous exécutons le script, nous voyons que la chaîne « elk » a été trouvée dans la chaîne « Whelkie », quels que soient les autres caractères qui l’entourent.
./whelkie.sh
Un point à noter est que nous n’entourons pas la chaîne de recherche de guillemets doubles. Si vous le faites, le globbing ne se produira pas. La chaîne de recherche sera traitée littéralement.
D’autres formes de coquillage sont autorisées. Le point d’interrogation « ?
” correspondra à des caractères uniques et des crochets simples sont utilisés pour indiquer des plages de caractères. Par exemple, si vous ne savez pas quel boîtier utiliser, vous pouvez couvrir les deux éventualités avec une fourchette.
#!/bin/bash stringvar="Jean-Claude van Clam" if [[ "$stringvar" == *[cC]lam* ]]; then echo "Warning contains seafood." else echo "Free from molluscs." fi
Enregistrez ce script sous le nom « damme.sh » et rendez-le exécutable. Lorsque nous l’exécutons, l’instruction conditionnelle est résolue en vrai et la première clause de l’instruction if est exécutée.
./damme.sh
Citer des chaînes
Nous avons mentionné plus tôt l’encapsulation des chaînes entre guillemets doubles. Si vous le faites, le shell globing ne se produira pas. Bien que la convention dise qu’il s’agit d’une bonne pratique, vous ne avoir besoin pour envelopper les variables de chaîne entre guillemets lors de l’utilisation [[
and ]]
même s’ils contiennent des espaces. Regardez l’exemple suivant. Les deux $stringvar
et $surname
les variables de chaîne contiennent des espaces, mais aucun n’est entre guillemets dans l’instruction conditionnelle.
#!/bin/bash stringvar="van Damme" surname="van Damme" if [[ $stringvar == $surname ]]; then echo "Surnames match." else echo "Surnames don't match." fi
Enregistrez-le dans un fichier appelé « surname.sh » et rendez-le exécutable. Exécutez-le en utilisant :
./surname.sh
Malgré les deux chaînes contenant des espaces, le script réussit et l’instruction conditionnelle est résolue à true. Ceci est utile lorsqu’il s’agit de chemins et de noms de répertoires contenant des espaces. Ici le -d
L’option renvoie true si la variable contient un nom de répertoire valide.
#!/bin/bash dir="/home/dave/Documents/Needs Work" if [[ -d ${dir} ]]; then echo "Directory confirmed" else echo "Directory not found" fi
Si vous modifiez le chemin dans le script pour refléter un répertoire sur votre propre ordinateur, enregistrez le texte dans un fichier appelé « dir.sh » et rendez-le exécutable, vous pouvez voir que cela fonctionne.
./dir.sh
EN RELATION: Comment travailler avec des variables dans Bash
Nom de fichier Globbing Gotchas
Une différence intéressante entre [ ]
et [[ ]]
se rapporte aux noms de fichiers avec globbing en eux. La forme « *.sh » correspondra à tous les fichiers de script. Utiliser des parenthèses simples [ ]
échoue à moins qu’il n’y ait un seul fichier de script. La recherche de plusieurs scripts génère une erreur.
Voici le script avec des conditions à crochet unique.
#!/bin/bash if [ -a *.sh ]; then echo "Found a script file" else echo "Didn't find a script file" fi
Nous avons enregistré ce texte dans « script.sh » et l’avons rendu exécutable. Nous avons vérifié combien de scripts se trouvaient dans le répertoire, puis avons exécuté le script.
ls
./script.sh
Bash renvoie une erreur. Nous avons supprimé tous les fichiers de script sauf un et avons réexécuté le script.
ls
./script.sh
Le test conditionnel renvoie true et le script ne provoque pas d’erreur. La modification du script pour utiliser des crochets doubles fournit un troisième type de comportement.
#!/bin/bash if [[ -a *.sh ]]; then echo "Found a script file" else echo "Didn't find a script file" fi
Nous l’avons enregistré dans un fichier appelé « dscript.sh » et l’avons rendu exécutable. L’exécution de ce script dans un répertoire contenant de nombreux scripts ne génère pas d’erreur, mais le script ne reconnaît aucun fichier de script.
L’instruction conditionnelle utilisant des doubles crochets ne se résout en vrai que dans le cas improbable où vous avez un fichier réellement appelé « *.sh » dans le répertoire.
./dscript.sh
ET et OU logiques
Les supports doubles vous permettent d’utiliser &&
et ||
comme opérateurs logiques ET et OU.
Ce script doit résoudre l’instruction conditionnelle sur true car 10 équivaut à 10 et 25 est inférieur à 26.
#!/bin/bash first=10 second=25 if [[ first -eq 10 && second -lt 26 ]]; then echo "Condition met" else echo "Condition failed" fi
Enregistrez ce texte dans un fichier appelé « and.sh », rendez-le exécutable et exécutez-le avec :
./and.sh
Le script s’exécute comme prévu.
Cette fois, nous utiliserons le ||
opérateur. L’instruction conditionnelle doit être résolue sur true car bien que 10 ne soit pas supérieur à 15, 25 est toujours inférieur à 26. Tant que la première comparaison ou la seconde comparaison est vraie, l’instruction conditionnelle dans son ensemble se résout en vrai.
Enregistrez ce texte sous le nom « or.sh » et rendez-le exécutable.
#!/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
Les instructions conditionnelles à double crochet permettent l’utilisation de la =~
opérateur, qui applique les modèles de recherche regex dans une chaîne à l’autre moitié de l’instruction. Si l’expression régulière est satisfaite, l’instruction conditionnelle est considérée comme vraie. Si l’expression régulière ne trouve aucune correspondance, l’instruction conditionnelle devient fausse.
EN RELATION: Comment utiliser des expressions régulières (regex) sous Linux
Enregistrez ce texte dans un fichier appelé « regex.sh » et rendez-le exécutable.
#!/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
Le premier ensemble de doubles crochets utilise la variable chaîne $mask1
comme regex. Il contient le modèle pour tous les chiffres dans la plage de zéro à neuf. Il applique cette regex au $words
variable de chaîne.
Le deuxième jeu de doubles crochets utilise à nouveau la variable chaîne $mask1
comme regex, mais cette fois, il l’utilise avec le $WordsandNumbers
variable de chaîne.
Le dernier ensemble de doubles crochets utilise un masque regex plus complexe dans la variable de chaîne $mask2
.
- [A-Za-z0-9._%+-]+: Cela correspond à n’importe quel caractère qui est une lettre majuscule ou minuscule, ou n’importe quel chiffre de zéro à neuf, ou un point, un trait de soulignement, un signe de pourcentage ou un signe plus ou moins. Le «
+
» en dehors du «[]
” signifie répéter ces correspondances pour autant de caractères qu’il en trouve. - @: Cela correspond au caractère « @ » uniquement.
- [A-Za-z0-9.-]+: Cela correspond à n’importe quel caractère qui est une lettre majuscule ou minuscule, ou n’importe quel chiffre de zéro à neuf, ou un point ou un trait d’union. Le «
+
» en dehors du «[ ]
” signifie répéter ces correspondances pour autant de caractères qu’il en trouve. - .: Cela correspond au « . » caractère seulement.
- [A-Za-z]{2,4}: Cela correspond à n’importe quelle lettre majuscule ou minuscule. Le «
{2,4}
” signifie correspondre à au moins deux caractères et au plus quatre.
En mettant tout cela ensemble, le masque regex vérifiera si une adresse e-mail est correctement formée.
Enregistrez le texte du script dans un fichier appelé « regex.sh » et rendez-le exécutable. Lorsque nous exécutons le script, nous obtenons cette sortie.
./regex.sh
La première instruction conditionnelle échoue car l’expression régulière recherche des chiffres mais il n’y a pas de chiffres dans la valeur contenue dans le $words
variable de chaîne.
La deuxième instruction conditionnelle réussit parce que le $WordsandNumbers
La variable de chaîne contient des chiffres.
L’instruction conditionnelle finale réussit, c’est-à-dire qu’elle devient vraie, car l’adresse e-mail est correctement formatée.
Une seule condition
Les tests conditionnels à double crochet apportent flexibilité et lisibilité à vos scripts. Le simple fait de pouvoir utiliser des regex dans vos tests conditionnels justifie d’apprendre à utiliser [[
and ]]
.
Assurez-vous simplement que le script appelle un shell qui les prend en charge, comme Bash.
EN RELATION: 15 caractères spéciaux que vous devez connaître pour Bash