FRFAM.COM >> Famille >> Technologie &Innovation >> Informatique

Tout ce que vous devez savoir sur Bash For Loops sous Linux

Les scripts bash sont un moyen très efficace d'automatiser les tâches, en particulier celles qui tirent parti d'autres programmes existants. Cette automatisation nécessite souvent de répéter plusieurs fois une opération similaire, c'est précisément là que la boucle for prend tout son sens.

Les administrateurs système Linux et Mac sont généralement familiarisés avec les scripts via le terminal, mais même les utilisateurs Windows peuvent participer à l'action avec le sous-système Windows pour Linux.

Fonctionnement des scripts Bash

Un script bash est simplement un fichier texte contenant une série de commandes que le shell bash peut lire et exécuter. Bash est le shell par défaut dans macOS pré-Catalina et dans la plupart des distributions Linux.

Si vous n'avez jamais travaillé avec un script shell auparavant, vous devriez commencer par le cas le plus simple. Cela vous permettra de mettre en pratique les concepts clés, y compris la création du script et son exécution.

Tout d'abord, créez le fichier suivant dans un emplacement pratique (idéalement, ouvrez un terminal et accédez d'abord au répertoire souhaité) :

#!/bin/bash 
echo "Hello, World"

La première ligne indique à tout ce qui exécute ce programme comment l'exécuter (c'est-à-dire en utilisant l'interpréteur bash). La seconde est juste une commande comme n'importe quelle autre que vous pourriez entrer sur la ligne de commande. Enregistrez ce fichier sous hello_world.sh , puis :

$ chmod +x hello_world.sh 
$ ./hello_world.sh

Le chmod La commande sur la première ligne rend le fichier exécutable, ce qui signifie qu'il peut être exécuté en tapant son nom, comme sur la deuxième ligne.

Si vous voyez les mots "Hello, World" apparaître imprimés sur une ligne de votre terminal, alors tout fonctionne comme prévu.

Comment fonctionnent les boucles For

En programmation générale, il existe deux principaux types de boucle for :numérique et foreach . Le type numérique est traditionnellement le plus courant, mais dans l'utilisation de bash, c'est généralement l'inverse.

Les boucles for numériques se concentrent généralement sur un seul entier qui détermine le nombre d'itérations à effectuer, par exemple :

for (i =0; i <100; i++) { 
/* instructions à exécuter de manière répétée */
}

Il s'agit d'une boucle for d'apparence familière qui itérera exactement 100 fois, à moins que i ne soit modifié dans la boucle, ou qu'une autre instruction n'interrompe l'exécution de la boucle for.

Les boucles foreach, en revanche, ont tendance à fonctionner sur des structures telles que des listes ou des tableaux, et itèrent pour chaque élément de cette collection :

personnes =[ "Pierre", "Paul", "Marie" ] 
foreach (personnes en tant que personne) {
si (personne =="Paul") {
...
}
}

Certains langages utilisent une syntaxe légèrement différente qui permute l'ordre de la collection et de l'élément :

personnes =[ "Pierre", "Paul", "Marie" ] 
pour (personne dans personnes) {
si (personne =="Paul") {
...
}
}

Boucles For in

En bash, le foreach ou for in - la boucle est plus courante. La syntaxe de base est simplement :

pour arg dans [liste] 
fais
/* instructions à exécuter de manière répétée */
/* la valeur de arg peut être obtenue avec $arg */
terminé

Par exemple, pour parcourir trois fichiers explicitement nommés :

pour le fichier dans un.c deux.c trois.c 
fais
ls "$fichier"
terminé

Si de tels fichiers existent dans le répertoire courant, la sortie de ce script sera :

one.c 
deux.c
trois.c

Au lieu d'un ensemble fixe de fichiers, la liste peut être obtenue via un modèle glob (qui inclut des caractères génériques - caractères spéciaux qui représentent d'autres caractères). Dans l'exemple suivant, la boucle for parcourt tous les fichiers (dans le répertoire courant) dont les noms se terminent par ".xml":

pour le fichier en *.xml 
fais
ls -l "$fichier"
terminé

Voici quelques exemples de sortie :

$ -rw-r--r-- 1 bobby staff 2436 3 novembre 2019 feed.xml 
$ -rw-r--r-- 1 bobby staff 6447 27 Oct 16:24 sitemap.xml

Cela peut ressembler à une façon de faire longue :

$ ls -l *.xml 

Mais il y a une différence significative :la boucle for exécute le ls programme 2 fois distinctes, avec un seul nom de fichier à chaque fois. Dans l'exemple séparé de ls, le modèle glob (*.xml) correspond d'abord aux noms de fichiers, puis les envoie tous, en tant que paramètres de ligne de commande individuels, à une instance de ls .

Voici un exemple qui utilise le wc (nombre de mots) pour rendre la différence plus évidente :

$ wc -l *.xml 
44 flux.xml
231 sitemap.xml
275 au total

Les wc programme compte le nombre de lignes dans chaque fichier séparément, puis imprime un nombre total sur chacun d'eux. En revanche, si wc fonctionne dans une boucle for :

pour le fichier en *.xml 
fais
wc -l $fichier
terminé

Vous verrez toujours le nombre de chaque fichier :

44 feed.xml 
231 sitemap.xml

Mais il n'y a pas de total récapitulatif global car wc est exécuté de manière isolée, à chaque itération de la boucle.

Quand une liste n'est pas une liste

Il y a une erreur très simple et courante lorsqu'il s'agit de boucles for, en raison de la façon dont bash gère les arguments/chaînes entre guillemets. Faire une boucle dans une liste de fichiers devrait être fait comme ceci :

pour le fichier dans un.c deux.c 

Pas comme ça :

pour le fichier dans "one.c two.c" 

Le deuxième exemple met les noms de fichiers entre guillemets doubles, ce qui donne une liste avec un seul paramètre ; la boucle for ne s'exécutera qu'une seule fois. Ce problème peut être évité en utilisant une variable dans de tels cas :

FILES="un.c deux.c" 
pour le fichier dans $FILES
fais
...
terminé

Notez que la déclaration de variable elle-même doit mettre sa valeur entre guillemets !

Pour sans liste

Sans rien à parcourir, une boucle for fonctionne sur tous les arguments de ligne de commande fournis au script lorsqu'il est invoqué. Par exemple, si vous avez un script nommé args.sh contenant les éléments suivants :

#!/bin/sh 
pour un
fais
echo $a
terminé

Ensuite, l'exécution de args.sh vous donnera ceci :

$ ./args.sh un deux trois 
une
deux
trois

Bash reconnaît ce cas et traite pour un faire comme l'équivalent de pour a dans $@ do où $@ est une variable spéciale représentant les arguments de la ligne de commande.

Émulation d'une boucle For numérique traditionnelle

Les scripts bash traitent souvent des listes de fichiers ou de lignes de sortie d'autres commandes, de sorte que le type de boucle for in est courant. Cependant, l'opération de style c traditionnelle est toujours prise en charge :

pour (( i=1; i<=5; i++ )) 
fais
écho $i
terminé

C'est le formulaire classique en trois parties dans lequel :

  1. une variable est initialisée (i=1) lors de la première rencontre de la boucle
  2. la boucle continue tant que la condition (i<=5) est vraie
  3. à chaque tour de boucle, la variable est incrémentée (i++)

L'itération entre deux valeurs est une exigence suffisamment courante pour qu'il existe une alternative plus courte et légèrement moins déroutante :

pour je dans {1..5} 
fais
écho $i
terminé

L'expansion des accolades qui a lieu traduit efficacement la boucle for ci-dessus en :

pour i dans 1 2 3 4 

Contrôle de boucle plus fin avec pause et continuer

Les boucles for plus complexes nécessitent souvent un moyen de quitter plus tôt ou de redémarrer immédiatement la boucle principale avec la valeur suivante à tour de rôle. Pour ce faire, bash emprunte les instructions break et continue qui sont courantes dans d'autres langages de programmation. Voici un exemple qui utilise les deux pour trouver le premier fichier contenant plus de 100 caractères :

#!/bin/bash 
pour fichier en *
fais
si [ ! -f "$fichier" ]
ensuite
echo "$file n'est pas un fichier"
Continuez
Fi
num_chars=$(wc -c <"$fichier")
echo $file contient "$num_chars caractères"
si [ $num_chars -gt 100 ]
ensuite
echo "Fichier $ trouvé"
Pause
Fi
terminé

La boucle for fonctionne ici sur tous les fichiers du répertoire courant. Si le fichier n'est pas un fichier normal (par exemple, s'il s'agit d'un répertoire), l'instruction continue est utilisée pour redémarrer la boucle avec le fichier suivant à tour de rôle. S'il s'agit d'un fichier normal, le deuxième bloc conditionnel déterminera s'il contient plus de 100 caractères. Si tel est le cas, l'instruction break est utilisée pour quitter immédiatement la boucle for (et atteindre la fin du script).

Conclusion

Un script bash est un fichier contenant un ensemble d'instructions pouvant être exécutées. Une boucle for permet de répéter plusieurs fois une partie d'un script. Avec l'utilisation de variables, de commandes externes et des instructions break et continue, les scripts bash peuvent appliquer une logique plus complexe et effectuer un large éventail de tâches.


[]