Les boucles While, Do-While et Do-Until
Sommaire
I. Présentation
Nous allons étudier le fonctionnement des boucles While, Do..Until et Do..While en PowerShell, car elles ont un rôle important à jouer dans vos scripts ! Elles sont bien différentes des boucles For et ForEach que nous avons déjà étudiés.
Avec une syntaxe très proche, voire identique, ces trois boucles ont malgré tout une logique différente. Pour notre plus grand plaisir, parce que ça nous offre plus de possibilités pour scripter ! Nous allons étudier le fonctionnement de ces boucles.
Ce chapitre est disponible au format vidéo :
II. La boucle While
A. Logique et syntaxe
Contrairement à la boucle "For" qui exécute un nombre spécifique de répétitions, et à la boucle "Foreach" qui parcourt chaque élément d'une collection, la boucle "While" continue à s'exécuter tant qu'une certaine condition est vraie.
Sur une ligne, elle s'écrit de la façon suivante :
While (condition) { instructions }
While (la condition est vrai){ exécute ce code }
En matière de logique, il faut bien comprendre que la boucle "While" vérifie d'abord la condition. Si la condition est vraie, elle exécute les instructions situées entre les accolades. Elle continue à vérifier la condition et à exécuter les instructions tant que la condition reste vraie, donc le nombre d'itérations pourra être variable. Cela signifie que si la condition est fausse dès le début, les instructions ne sont jamais exécutées et le script poursuit son exécution.
B. Exemple n°1
Commençons par un exemple très simple, mais indispensable pour bien comprendre le fonctionnement d'une boucle "While" en pratique. Au début, la variable "$i", que nous aurions pu appeler autrement, est égale à 0. Nous allons faire en sorte d'afficher dans la console la valeur de "$i" tant que sa valeur est inférieure ou égale à 20. La condition sera donc celle-ci :
$i -le 20
Si nous intégrons ceci dans une boucle "While", nous obtenons :
# Initialiser la variable $i à 0
$i = 0
# Tant que $i est inférieur ou égal à 20, nous affichons le contenu de $i dans la console
While ($i -le 20) {
# Afficher la valeur de $i dans la console
Write-Output $i
# Incrémenter la valeur de $i de 1
$i++
}
Write-Output "Nous sommes en dehors de la boucle While !"
À l'exécution, la condition "$i -le 20" est vraie, donc la boucle va s'exécuter. Après chaque itération de la boucle, la valeur de "$i" est incrémentée de 1. Lorsque "$i" atteindra 21, la condition "$i -le 20" deviendra fausse, donc la boucle s'arrêtera !
Si vous remplacez "$i = 0" par "$i = 21", alors vous verrez que le code contenu dans la boucle While ne sera jamais exécuté puisque la condition est évaluée avant l'exécution du code.
B. Exemple n°2
Nous allons utiliser la boucle "While" dans un second exemple. Cette fois-ci, notre script attendra, grâce à la boucle While, que le processus d'une application spécifique, par exemple "notepad.exe" (Bloc-notes), soit terminé avant de continuer à exécuter la suite du script. Donc, à chaque fois, si le processus notepad.exe est toujours en cours d'exécution, nous allons déclencher une pause de 3 secondes, puis réévaluer la condition, etc.
# Récupérer le processus "notepad" (on masque l'erreur qui sera renvoyée s'il n'est pas en cours d'exécution)
$Processus = Get-Process "notepad" -ErrorAction SilentlyContinue
# Tant que le processus "notepad" est en cours d'exécution, nous patientons 1 seconde
While ($processus) {
# Afficher un message dans la console - Processus toujours en cours
Write-Output "L'application notepad est toujours en cours d'exécution."
# Attendre 3 seconde avant de vérifier à nouveau
Start-Sleep -Seconds 3
# Vérifiez si le processus "notepad" est en cours d'exécution
# Ligne obligatoire, sinon la valeur de la variable $Processus n'évoluera jamais !
$Processus = Get-Process "notepad" -ErrorAction SilentlyContinue
}
# Fin de la boucle - Message de validation
Write-Output "L'application notepad n'est plus en cours d'exécution. Le script peut continuer à s'exécuter."
Ce qui pourra donner un résultat comme celui-ci :
# Bloc-notes ouvert sur l'ordinateur
L'application notepad est toujours en cours d'exécution.
L'application notepad est toujours en cours d'exécution.
L'application notepad est toujours en cours d'exécution.
# Fermeture du Bloc-notes sur l'ordinateur
L'application notepad n'est plus en cours d'exécution. Le script peut continuer à s'exécuter.
Pour approfondir ce sujet, vous pouvez lire cet article :
III. La boucle Do While
A. Logique et syntaxe
La boucle "Do-While" est très proche de la boucle "While", sauf que sa syntaxe est légèrement différente grâce à l'introduction du "Do". Ceci n'est pas neutre puisque cela signifie que la condition est évaluée après l'exécution du code présent dans la boucle. Autrement dit, le code sera obligatoirement exécuté une fois puisque la condition est évaluée après, alors qu'avec la boucle "While", la condition est évaluée en amont.
La boucle "Do-While" exécute d'abord les instructions présentes dans la boucle, puis elle vérifie la condition. Si la condition est vraie, elle exécute à nouveau les instructions. Nous pouvons même affirmer qu'elle continue à exécuter les instructions et à vérifier la condition tant que la condition est vraie. Si la condition est fausse, la boucle est arrêtée comme avec le "While" seul.
La boucle "Do-While" suit la logique suivante :
Do{code} While(la condition est vraie)
Autrement dit :
Joue{ce code} Tant que (la condition est vraie)
Dans le cas de "Do While" on se dit "Je joue le code tant que la condition est vraie" alors que dans la boucle "While" on se dit "Tant que la condition est vraie, je joue le code".
B. Exemple n°1
Nous allons reprendre le même exemple que pour la boucle "While", mais en l'écrivant sous la forme d'une boucle "Do-While". Au début, la variable "$i", que nous aurions pu appeler autrement, est égale à 0. Nous allons faire en sorte d'afficher dans la console la valeur de "$i" tant que sa valeur est inférieure ou égale à 20.
# Initialiser la variable $i à 0
$i = 0
# Exécuter les instructions, puis vérifier si $i est inférieur ou égal à 20
do {
# Afficher la valeur de $i dans la console
Write-Output $i
# Incrémenter la valeur de $i de 1
$i++
} while ($i -le 20)
Write-Output "Nous sommes en dehors de la boucle Do-While !"
La logique est légèrement différente, mais nous obtenons le même résultat :
Finalement, pour choisir entre "While" et "Do-While", posez-vous la question suivante : est-ce que je souhaite que le code présent dans la boucle soit exécuté au moins une fois ?
B. Exemple n°2
A titre indicatif, voici un second exemple. Ici, nous allons initialiser la variable "$i" afin de lui associer la valeur 0, et tant que l'application Bloc-notes est en cours d'exécution, nous allons indiquer la valeur de "$i" dans la console. A chaque itération, "$i" est incrémenté de 1.
# Initialiser la variable $i à 0 $i = 0 # Exécuter les instructions tant que le processus notepad est en cours d'exécution Do{ $i++ Write-Output $i }While(Get-Process -Name "notepad" -ErrorAction SilentlyContinue) Write-Output "L'applicaiton Notepad est fermée, nous pouvons continuer !"
Nous pouvons voir dans la console que nous sortons de la boucle dès que je ferme l'application Bloc-notes sur ma machine :
IV. La boucle Do Until
A. Logique et syntaxe
La boucle "Do-Until" est une troisième structure de contrôle importante en PowerShell. Bien qu'elle soit similaire à la boucle "Do-While", il y a tout de même une différence majeure : au lieu de répéter les instructions tant que la condition est vraie (comme dans "Do-While"), la boucle "Do-Until" répète les instructions jusqu'à ce que la condition devienne vraie.
La boucle "Do-Until" en PowerShell fonctionne selon la logique suivante :
Do{code} Until(la condition soit vraie)
Autrement dit :
Joue {ce code} Jusqu'à ce que (la condition soit vraie)
Ce qui peut-être intéressant notamment pour vérifier un état dans le "Do" et dès que l'état attendu arrivera, on sortira de la boucle. Il y a de nombreux cas d'utilisation de ce type de boucle, cela peut notamment servir de temporisation dans un script pour attendre qu'un état bascule sur l'état attendu avant de continuer. Pour obtenir le même comportement qu'avec une boucle "Do-While", il convient d'inverser la logique de la condition.
B. Exemple n°1
Nous allons reprendre le même premier exemple que pour les boucles "While" et "Do-While", mais en l'adaptant sous la forme d'une boucle "Do-Until". Au début, la variable "$i", que nous aurions pu appeler autrement, est égale à 0. Nous allons faire en sorte d'afficher dans la console la valeur de "$i" tant que sa valeur est inférieure ou égale à 20.
C'est relativement simple et rapide puisqu'il suffit de remplacer le mot clé "While" par "Until", puis d'inverser la condition en utilisant un opérateur de comparaison différent. Ici, nous allons répéter la boucle jusqu'à ce (until) "$i" soit plus grand que 20, puisque nous souhaitons avoir les valeurs de 0 à 20.
# Initialiser la variable $i à 0
$i = 0
# Exécuter les instructions, puis vérifier si $i est inférieur ou égal à 20
do {
# Afficher la valeur de $i dans la console
Write-Output $i
# Incrémenter la valeur de $i de 1
$i++
} until ($i -gt 20)
Write-Output "Nous sommes en dehors de la boucle Do-Until !"
Nous obtenons bien un résultat identique et surtout, c'est le résultat que nous attendions.
C. Exemple n°2
Pour ce second exemple, nous allons voir que nous pouvons ajouter plusieurs conditions dans les boucles "Do-Until", mais aussi "Do-While" et "While". Admettons que nous avons aussi une variable "$j" qui s'incrémente de 1 à chaque tour de boucle... Comme la variable "$i". Toutefois, nous allons initialiser cette variable à 5 alors que "$i" est initialisé à 0. Nous souhaitons sortir de la boucle dès que "$i" ou "$j" atteint 10 :
# Initialiser la variable $i à 0 $i = 0 # Initialiser la variable $j à 5 $j = 5 # Exécuter les instructions, puis vérifier si $i est inférieur ou égal à 20 do { # Afficher les valeurs de $i et $j Write-Output "i = $i - j = $j" # Incrémenter la valeur de $i et de $j de 1 $i++ $j++ } until (($i -gt 10) -or ($j -gt 10)) Write-Output "Nous sommes en dehors de la boucle Do-Until !"
Vous remarquerez que nous encadrons chaque condition par des parenthèses de la même manière que nous le faisons dans une structure conditionnelle avec If. De plus, nous utilisons l'opérateur "-or", mais nous pourrions aussi utiliser un autre opérateur tel que "-and", selon ce que l'on souhaite faire.
Voici le résultat obtenu :
Nous sortons bien de la boucle dès que "$j" est supérieur à 10, même si "$i" n'a pas encore atteint ce nombre.
V. Conclusion
Les boucles "While", "Do-While" et "Do-Until" sont également très pratiques et parfaitement adaptées à certains scénarios, comme nous l'avons vu.
Un autre cas d'usage très intéressant, c'est lorsque nous demandons à un opérateur de saisir une information, par exemple, un mot de passe : nous pouvons contrôler la longueur et la complexité de la chaine, et si elle ne répond pas aux besoins, nous pouvons à demander à ce qu'une nouvelle valeur soit saisie jusqu'à ce que la valeur respecte nos besoins. Vous voyez, en écrivant ce besoin, j'ai utilisé le terme "Jusqu'à" donc nous pourrions le traduire avec une boucle "Do-Until", ou "Do-While", d'ailleurs.