Ceci est le deuxième article d'une série axée sur les scripts Gnu Bash. Dans le premier article sur les scripts bash, nous venons de créer le script le plus simple :des commandes simples, les unes après les autres. Nous avons également vu certaines variables utilisées. Cet article couvrira les structures de contrôle bash.
Structures de contrôle
Comme je l'ai dit dans l'article précédent, la paresse est la clé du succès. Si je dois exécuter certaines commandes, un peu plus tard, les mêmes commandes dans le même ordre, la troisième fois, j'ouvrirai un éditeur de texte et collerai ces commandes pour l'enregistrer en tant que script.
Après quelques jours plus tard, ce script commence à se développer, à la fois en extension et en complexité. J'ai besoin de moyens pour contrôler le flux d'exécution, par exemple :
- si quelque chose se passe, faites quelque chose, ou si quelque chose ne se passe pas, faites autre chose ;
- pendant que quelque chose se passe, faire quelque chose encore et encore, ou faire quelque chose encore et encore ;
- ou selon la valeur d'une variable ou ce qui s'est passé, faire ceci ou cela ou autre,
- etc
C'est à cela que sont destinées les structures de contrôle bash (en fait, en bash ou dans tout autre langage de programmation). Mais d'abord, nous devons savoir :
État de sortie
À partir de la page de manuel bash :
«Le statut de sortie d'une commande exécutée est la valeur renvoyée par l'appel système waitpid ou une fonction équivalente. Les statuts de sortie sont compris entre 0 et 255. (…) Un statut de sortie de zéro indique un succès (ou égal à "vrai"). Un état de sortie différent de zéro indique un échec (ou, égal à 'false').(…. Par exemple :) Si une commande n'est pas trouvée, le processus enfant créé pour l'exécuter renvoie un statut de 127. Si une commande est trouvée mais n'est pas exécutable, le statut de retour est 126 ».
tl;dr :les statuts de sortie de 0 signifie vrai , Succès; toute autre valeur signifie faux . Il est important d'apprendre cela car effectuer des décisions vrai/faux revient à vérifier l'état de sortie d'une commande.
Bash stocke le statut de sortie de la dernière commande exécutée dans le $? variables.
si-alors-sinon
C'est le si quelque chose arrive (quelque chose se passe signifie une commande avec un état de sortie de zéro) faites quelque chose , ou bien faire autre chose. La syntaxe est :
if command then command1 command2 ... else commandA commandB ... fi
Comme vous pouvez le voir sur la capture d'écran, il peut être écrit sur une seule ligne, en séparant chaque commande par un point-virgule :
commandeif command; then command1; command2;...; else commandA; commandB;...;fi
En fonction de la complexité du bloc if-then, il peut être plus facile à lire ou plus difficile à lire le style "oneliner".
Et si vous voulez exécuter une commande si quelque chose se passe, exécutez une autre commande uniquement si quelque chose d'autre arrive? utilisez le mot clé elif (else if):
if command then command1 command2 ... elif other_command commandA commandB ... else another block of commands fi
Un bloc if-then-else se termine par le mot clé fi (si à l'envers).
Comparaison de chaînes et de nombres
Vous vous souvenez des variables ? souvent il se passe quelque chose c'est qu'en fonction de la valeur d'une variable on veut exécuter certaines commandes ou autre.
Pour comparer si une chaîne est égale à un mot ou un nombre est inférieur à un autre, nous utilisons la commande test . La syntaxe générale est :
test expression
Si expression est omis, il est considéré comme faux (état de sortie> 0). Si expression est juste une chaîne de texte, c'est vrai. Cela pourrait être délicat, par exemple :
$ test false; echo $? 0
Nous ne testons pas le statut de sortie de la commande false (il existe une commande false ) mais la chaîne false contre rien. L'autre façon d'exécuter la commande de test consiste à entourer l'expression de crochets. Cette autre méthode est plus facile à lire à l'intérieur d'un bloc if-then-else.
opérandes | vrai si |
expression | vrai |
! expression | false (inverse l'expression) |
expressionA -a expressionB | Et. les deux expressions sont vraies |
expressionA -o expressionB | Ou. une des expressions est vraie |
chaîne1 =chaîne2 | les deux chaînes sont égales |
chaîne1 !=chaîne2 | les chaînes sont différentes |
int1 -eq int2 | entier1 est égal à entier2 |
int1-ge int2 | int1>=int2 |
int1 -gt int2 | int1> int2 |
int1 -le int2 | int1 <=int2 |
int1 -lt int2 | int1 |
int1 -ne int2 | int1 n'est pas égal à int2 |
-e fichier | le fichier existe |
-d répertoire | le fichier existe et est un répertoire |
Il y a plus d'expressions, ce sont celles que je considère les plus importantes. Lisez la page de manuel de test pour apprendre les autres expressions.
Faites attention à ce qu'il y ait un espace entre les crochets et l'expression. Maintenant, nous pouvons utiliser test pour faire quelque chose en fonction de la valeur d'une variable. Par exemple :
cas
Lorsque nous voulons tester une variable par rapport à plusieurs valeurs, nous pouvons ajouter plusieurs elif à notre bloc if-then-else comme ceci :
if [ $a = "value1" ] then command1 for value1 ... commandN for value1 elif [ $a = "value2" ] then command1 for value2 ... commandN for value2 ... elif [ $a = "valueN" ] then command1 for valueN ... commandN for valueN else command1 for every other value ... commandN for every other value fi
Ou nous pouvons remplacer par une commande case qui est plus facile à lire et à écrire :
case expression in value1) command1 for value1 ... commandN for value1 ;; value2) command1 for value2 ... commandN for value2 ;; ... *) command1 for every other value ... commandN for every other value ;; esac
De plus, moins de frappes au clavier, n'oubliez pas d'être assez paresseux pour faire fonctionner l'ordinateur pour vous. La dernière valeur * est le cas par défaut, toutes les autres valeurs non appariées auparavant. Casse à l'envers, esac , est analogue à la déclaration fi. Si le ;; est utilisé, aucune correspondance ultérieure n'est tentée après la première correspondance de modèle. Pour tester le motif suivant, utilisez ;;* opérateur. Par exemple :
pendant et jusqu'à
Pendant que c'est faire quelque chose encore et encore pendant que quelque chose se passe. Et jusqu'à ce que ce soit pareil mais nié (faire quelque chose encore et encore pendant que quelque chose ne se passe pas). La syntaxe générale est :
while command do command1 command2 ... commandN done
Pour faire quelque chose pendant qu'il ne se passe pas (c'est-à-dire que l'état d'existence est différent de 0), remplacez while par jusqu'à. Voir quelques exemples :
Remarquez qu'ils n'ont pas produit le même résultat. Sur le bloc while, quand $a atteint la valeur 4, n'est pas plus bas que 4, donc le test est évalué faux (et le code de sortie est> 0). Sur le bloc until, lorsque $a atteint la valeur 4, n'est pas supérieur à 4.
Une horloge dans votre terminal
Parfois, je teste un cronjob et cela me rend anxieux jusqu'à ce qu'il soit exécuté. J'utilise la commande true (qui, comme vous l'avez peut-être deviné, produit un état de sortie 0) comme condition, et j'exécute la commande date encore et encore :
while true do date sleep 1 clear done
Cela fonctionnerait plus, mais je peux interrompre avec ctrl-c.
for-in -faire
Ce type de boucle itère sur une liste fournie en attribuant chaque élément à une variable. Syntaxe :
for i in list of words do command1 ... commandN done
C'est plus facile à voir dans un exemple :
Restez à l'écoute
Les choses deviennent complexes, mais nous voulons que nos scripts prennent certaines décisions pour faire ceci ou cela. Je devais couvrir d'autres sujets, mais cet article sur les structures de contrôle bash a trop grossi.
Sur les prochains, je couvrirai les tuyaux et la redirection. Je reviendrai probablement à ces structures de contrôle bash avec les exemples, quelque chose comme utiliser la sortie d'une commande dans une boucle for-in et des trucs comme ça.