Boucles de bash avec des exemples
- 2079
- 96
- Mohamed Brunet
Prêt à plonger dans une boucle bash? Avec la popularité de Linux en tant que système d'exploitation libre et armé de la puissance de l'interface de ligne de commande bash, on peut aller encore plus loin, codant des boucles avancées directement à partir de la ligne de commande, ou dans des scripts bash.
Exploitant cette puissance, on peut manipuler n'importe quel document, n'importe quel ensemble de fichiers ou implémenter des algorithmes avancés de presque tous les types et saveurs. Il est peu probable que vous ayez des limites si vous utilisez Bash comme base de vos scripts et que Bash Loops en forme une partie puissante.
Cela dit, les boucles de bash peuvent parfois être difficiles en termes de syntaxe et les connaissances environnantes sont primordiales. Aujourd'hui, nous vous présentons avec vous un ensemble d'exemples de boucle bash pour vous aider à augmenter rapidement et à devenir compétent en boucle bash! Commençons!
Dans ce tutoriel, vous apprendrez:
- Comment la dénigrement
pour
,alors que
etjusqu'à
Les boucles basées fonctionnent, avec des exemples - Comment bash nécessite la fin des déclarations de démarrage en boucle avant la section DO… FAIT de la boucle peut suivre, et comment cela se rapporte à If et à d'autres déclarations
- Comment implémenter des boucles basses de base et moyennes avancées
- Comment fonctionnent les sous-coquilles et comment ils peuvent être utilisés à l'intérieur des déclarations de portée de la boucle Bash
- Comment commencer à coder les boucles défensivement, en évitant les erreurs dans la sortie
- Comment coder
doublure
(un terme commun utilisé parmi les développeurs bash) sur la ligne de commande par rapport à implémenter le même code dans un script bash - Comment le
;
L'idiome de syntaxe est une question importante en ce qui concerne le codage de boucles de bash, à la fois sur la ligne de commande et dans les scripts
Exemples de boucles de bash
- Commençons par un base
pour
boucle:
Copie$ pour i en $ (SEQ 1 5); faire écho $ i; fait 1 2 3 4 5
Comme vous pouvez le voir, basique
pour
Les boucles en bash sont relativement simples à mettre en œuvre. Voici les étapes:pour: Indique que nous voulons démarrer une nouvelle boucle basée
je: une variable que nous utiliserons pour stocker la valeur générée par la clause à l'intérieur dudans
mot-clé (à savoir la séquence juste en dessous)
$ (SEQ 1 5): Ceci exécute une commande dans une autre sous-coque.Pour comprendre comment cela fonctionne, considérez cet exemple:
Copie$ seq 1 5 1 2 3 4 5
En gros, le
$ ()
la syntaxe peut être utilisée chaque fois (et partout!) Vous voulez démarrer une nouvelle sous-coquille. C'est l'une des fonctionnalités les plus puissantes de la coquille de bash. Considérez par exemple:
Copie$ test de chat.txt 1 2 $ echo "$ (test de chat.txt | tête -n1) "1
Comme vous pouvez le voir, ici le sous-coquille a exécuté 'Cat Test.txt | tête -n1 '(' tête -n1 'ne sélectionne que la première ligne) puis a fait écho à la sortie de ce sous-coquille.
Continuons à analyser notre boucle ci-dessus:
;: C'est très important. Dans Bash, toute «action», comme par exemple un test de déclaration «pour», ou un test de déclaration «if», ou une boucle de temps, etc. doit être résilié par un ';'. Ainsi, le ';' est ici * avant * le faire, pas après. Considérez cela très similaire si l'exemple:
Copie$ si ["a" == "a"]; Puis écho "Oui!"; fi oui!
Remarquez comment encore le
;
est avant lealors
, pas après. Veuillez ne pas laisser cela vous confondre pendant les scripts pour ou pendant que des boucles, si les déclarations, etc. N'oubliez pas que chaque action doit être résiliée avant toute nouvelle action, et doncpour
ousi
doit être résilié avant la prochaine action qui est «alors» dans l'exemple de l'instruction if, etfaire
Dans la boucle pour!Enfin, nous avons:
faire: Indiquant que
pour
Ce qui vient avant… faire…
Ce qui vient ci-après. Notez à nouveau que ce mot d'action est après la clôture;
utilisé pour fermer la déclaration d'ouverture de la boucle pour.
echo $ i: Ici, nous étendons la valeur stockée dans leje
variable ($ i
)
;: Terminer la déclaration d'écho (terminer chaque action)
fait: Indiquez que c'est la fin de notre boucle - Prenons ce même exemple, mais écrivons-le différemment:
Copie$ pour i en 1 2 3 4 5; faire écho $ i; fait 1 2 3 4 5
Vous pouvez voir maintenant comment cela se rapporte à l'exemple ci-dessus; C'est le même commentaire, bien que nous n'ayons pas utilisé de sous-coquille pour générer une séquence d'entrée pour nous, nous l'avons spécifié manuellement.
Est-ce que cela fait une tête de course sur les utilisations possibles un peu? Alors ça devrait 🙂 faire quelque chose de cool avec ça maintenant.
- Augmenter la complexité de notre boucle pour les fichiers:
Copie$ ls 1.txt 2.txt 3.txt 4.txt 5.SMS
Copie$ head -n1 *.txt ==> 1.SMS <== 1 ==> 2.SMS <== 1 ==> 3.SMS <== 1 ==> 4.SMS <== 1 ==> 5.SMS <== 1
Copie$ pour je dans $ (ls *.SMS); Do Cat "$ i" | tête -N1; fait 1 1 1 1 1
Pouvez-vous déterminer ce qui se passe ici? En regardant les nouvelles parties de ceci pour la boucle, nous voyons:
$ (ls *.SMS): Cela répertoriera tous les fichiers TXT dans le répertoire actuel et notera que le nom de ces fichiers sera stocké dans leje
variable, un fichier per / pour chaque boucle lepour
la boucle passera à travers.En d'autres termes, la première fois que la boucle (la pièce entre DO et Terminé) se produit,
$ i
contiendra1.SMS
. La prochaine course$ i
contiendra2.SMS
et ainsi de suite.Cat "$ i" | tête -N1: Ici nous prenons le
$ i
variable (comme nous l'avons vu1.SMS
, suivie par2.SMS
etc.) et chat ce fichier (l'afficher) et prendre la première ligne de la mêmetête -N1
. Ainsi, 5 fois1
est la sortie, car c'est la première ligne dans les 5 fichiers comme nous pouvons le voir depuis le précédenttête -N1
dans l'ensemble .fichiers txt. - Que diriez-vous d'un très complexe maintenant?
Copie$ tail -n1 *.txt ==> 1.SMS <== 1 ==> 2.SMS <== 2 ==> 3.SMS <== 3 ==> 4.SMS <== 4 ==> 5.SMS <== 5
Copie$ pour je dans $ (ls *.txt 2> / dev / null); faire echo -n "$ (tail -n1 $ i)"; Echo "de $ i !"; fait 1 de 1.SMS ! 2 de 2.SMS ! 3 de 3.SMS ! 4 de 4.SMS ! 5 de 5.SMS !
Pouvez-vous vous entraîner ce qui se passe ici?
Analysons-le pas à pas.
Pour moi dans : Nous le savons déjà; Recommencer à nouveau
pour
boucle, affectez la variable i à tout ce qui suit dans ledans
clause
$ (ls *.txt 2> / dev / null): Le même que la commande ci-dessus; Énumérez tous les fichiers TXT, mais cette fois avec un peu de protection définitive pour éviter les erreurs en place. Regarder:$ pour je dans $ (ls i.faire.pas.exister); faire écho à "tester simplement la non-existence des fichiers"; fait ls: ne peut pas accéder à 'i.faire.pas.exister ': aucun fichier ou répertoire de ce type
Sortie pas très professionnelle! Ainsi;
$ pour je dans $ (ls i.faire.pas.existe 2> / dev / null); faire écho à "tester simplement la non-existence des fichiers"; fait
Aucune sortie n'est générée par cette instruction.
Continuons notre analyse:
; faire: terminer l'énoncé de démarrage de la boucle pour commencer la section DO… terminée de notre définition de boucle
echo -n "$ (tail -n1 $ i)";: Premièrement, le-n
représente Ne pas sortir la nouvelle ligne de fuite à la fin de la sortie demandée.Ensuite, nous prenons la dernière ligne de chaque fichier. Notez comment nous avons optimisé notre code d'en haut? je.e. au lieu de faire
dossier de chat.txt | queue -N1
on peut simplement faireFichier Tail -N1.SMS
- un sténographie que les nouveaux développeurs bash pourraient facilement manquer. En d'autres termes, ici nous une simple impression1
(La dernière ligne en 1.txt) immédiatement suivi de2
pour2.SMS
etc.
En tant que sidenote, si nous n'avons pas spécifié la commande de suivi Echo, la sortie aurait simplement été
12345
sans aucune nouvelle ligne:
Copie$ pour je dans $ (ls *.txt 2> / dev / null); faire echo -n "$ (tail -n1 $ i)"; fait 12345 $
Remarquez comment même la dernière nouvelle ligne n'est pas présente, d'où la sortie avant l'invite
$
Retour.Enfin nous avons
Echo "de $ i !"
(nous montrant leÀ partir de 1.SMS !
sortie) et la fermeture de la boucle par lefait
.J'espère maintenant que vous pouvez voir à quel point cela est puissant et combien de contrôle que l'on peut exercer sur les fichiers, le contenu des documents et plus!
Générons une longue chaîne aléatoire avec une boucle! Amusant?
- En utilisant une boucle de temps pour générer une chaîne aléatoire:
Copie$ Random = "$ (date +% s% n | Cut -B14-19)" $ count = 0; Myrandom =; tandis que c'est vrai; Do count = $ [$ count + 1]; si [$ count -gt 10]; puis se briser; Fi; Myrandom = "$ myrandom $ (echo" $ random "| sed 's | ^ \ (.\).* | \ 1 | ') "; fait; echo" $ myrandom "6421761311
Qui a l'air complexe! Analyons-le pas à pas. Mais d'abord, voyons à quoi cela ressemblerait à l'intérieur d'un script bash.
- Exemple des mêmes fonctionnalités, implémentées dans un script bash:
Copie$ test de chat.sh #!/ bin / bash random = "$ (date +% s% n | coupe -b14-19)" count = 0 myrandom = while true; Do count = $ [$ count + 1] si [$ count -gt 10]; Ensuite, brisez fi myrandom = "$ myrandom $ (echo" $ random "| sed 's | ^ \ (.\).* | \ 1 | ') "fait echo" $ myrandom "
$ chmod + x test.sh $ ./test.SH 1111211213 $ ./test.SH 1212213213
Il est parfois surprenant que un tel code de boucle de bash complexe puisse si facilement être déplacé dans une `` une lignée ' lignes simples (ou au maximum).
Commençons maintenant à analyser nos deux derniers exemples - qui sont très similaires. Les petites différences de code, en particulier autour de l'idiome '; sont expliqués dans Exemple 7 dessous:
Random = "$ (date +% s% n | Cut -B14-19)" sur la ligne 4: cela prend (en utilisant
Cut -B14-19
) les 6 derniers chiffres de l'époque de l'époque actuelle (le nombre de secondes qui se sont écoulées depuis le 1er janvier 1970) tels que rapportés parDate +% s% n
et attribue cette chaîne générée à la variable aléatoire, définissant ainsi une entropie semi-aléatoire au pool aléatoire, en termes simples "rendant la piscine aléatoire un peu plus aléatoire".
Comte = 0 en ligne 6: définissez leCOMPTER
variable à0
Myrandom = en ligne 7: définissez leMyrandom
variable à «vide» (aucune valeur attribuée)
tandis que… faire… fait Entre la ligne 9 et la ligne 15: Cela devrait être clair maintenant; Commencez une boucle de temps, exécutez le code entre les clauses DO….
vrai: Et tant que l'énoncé qui suit le `` while '' est évalué comme vrai, la boucle continuera. Ici, la déclaration est «vrai», ce qui signifie qu'il s'agit d'une boucle indéfinie, jusqu'à uncasser
La déclaration est donnée.
Count = $ [$ count + 1] sur la ligne 10: augmenter notreCOMPTER
variable par1
si [$ count -gt 10]; alors sur la ligne 11: une instruction IF pour vérifier si notre variable est plus élevée alors-GT 10
, et si oui, exécutez alors…Fi
partie
casser sur la ligne 12: cela brisera l'indéfini pendant la boucle (i.e. quandCOMPTER
est plus grand alorsdix
La boucle se terminera)
Myrandom = "… sur la ligne 14: nous allons attribuer une nouvelle valeur àMyrandom
$ Myrandom Sur la ligne 14: Tout d'abord, prenez ce que nous avons déjà à l'intérieur de cette variable, en d'autres termes, nous allons ajouter quelque chose à la fin de ce qui est déjà là, et cela pour chaque boucle suivante
$ (echo "$ random" | SED 'S | ^ \ (.\).* | \ 1 | ') sur la ligne 14: c'est la pièce qui est ajoutée à chaque fois. Fondamentalement, cela fait écho àALÉATOIRE
variable et prend le premier caractère de cette sortie en utilisant une expression régulière complexe dans SED. Vous pouvez ignorer cette partie si vous le souhaitez, en gros, il indique "Prenez le premier caractère du$ Aléatoire
Sortie variable et jetez tout le reste "Vous pouvez donc voir comment la sortie (par exemple
1111211213
) est généré; un caractère (gauche à droite) à l'époque, en utilisant la boucle while, qui boucledix
fois à la suite duCOMPTER
Vérification de contre-variable.Alors pourquoi la sortie est-elle souvent dans le format de
1
,2
,3
et moins d'autres nombres? C'est parce que leALÉATOIRE
la variable renvoie une variable semi-aléatoire (basée sur leAléatoire =…
graine) qui est dans la plage de 0 à 32767. Ainsi, ce nombre commencera souvent par 1, 2 ou 3. Par exemple, 10000-19999 reviendra tous1
etc. Comme le premier caractère de la sortie est toujours pris par le SED! - Un court script pour mettre en évidence la possibilité d'organiser (ou de style) de bash en boucle de boucle d'une manière différente sans utiliser le
;
idiome.Nous devons clarifier les petites différences du script bash par rapport au script de ligne de commande à une ligne.
NOTE
Notez que dans le script bash (test.sh) il n'y a pas autant;
expressions idiomatiques. En effet, nous avons maintenant divisé le code sur plusieurs lignes et un;
est pas requis lorsqu'il y a un caractère EOL (fin de ligne) à la place. Un tel personnage (Newline ou Return Return) n'est pas visible dans la plupart des éditeurs de texte, mais il est explicite si vous pensez au fait que chaque commande est sur une ligne distincte.Notez également que vous pouvez placer le
faire
clause dualors que
boucle sur la ligne suivante également, afin qu'il devienne inutile d'utiliser même le;
là.
Copie$ Cat test2.sh #!/ bin / bash pour i dans $ (seq 1 3) faire écho "… boucle… $ je…" fait
$ ./ test2.sh… boucle… 1… boucle… 2… boucle… 3…
Personnellement, je préfère de loin le style de syntaxe donné dans Exemple 6, car il semble plus clair quelle est l'intention du code en écrivant l'instruction de la boucle en totalité sur une ligne (comme d'autres langues de codage), bien que les opinions et les styles de syntaxe diffèrent par développeur, ou par communauté de développeurs.
- Enfin, jetons un coup d'œil à un bash 'jusqu'à la boucle:
Copie$ Nr = 0; jusqu'à [$ nr -eq 5]; faire écho "$ nr"; Nr = $ [$ nr + 1]; fait 0 1 2 3 4
Analysons cet exemple:
Nr = 0: Ici, définissez une variable nommée
NR
, à zéro
jusqu'à: Nous commençons notre boucle «jusqu'à»
[$ Nr -eq 5]: C'est notresi
condition, ou mieux notrejusqu'à
condition. je dissi
Comme la syntaxe (et le travail) est similaire à celle de la commande de test, je.e. la commande sous-couche qui est utilisée danssi
affirmations. En bash, la commande de test peut également être représentée par un seul["]
supports. Le$ Nr -eq 5
tester des moyens; Lorsque notre variableNR
atteint 5, alors le test deviendra vrai, ce qui en fait lejusqu'à
La boucle se termine lorsque la condition est appariée (une autre façon de le lire est comme «jusqu'à ce que le vrai» ou «jusqu'à ce que notre variable NR soit égale à 5»). Notez qu'une fois que NR est 5, le code de boucle n'est plus exécuté, donc 4 est le dernier numéro affiché.
;: Terminer notre déclaration jusqu'à ce que l'explique ci-dessus
faire: Démarrez notre chaîne d'action à exécuter jusqu'à ce que la déclaration testée devienne vraie / valide
Echo "$ nr;":écho
Out la valeur actuelle de notre variableNR
Nr = $ [$ nr + 1];: Augmenter notre variable d'un. Le$ ['…']
La méthode de calcul est spécifique à Bash
fait: Terminer notre chaîne d'action / code de boucleComme vous pouvez le voir, tandis que et jusqu'à ce que les boucles soient de nature très similaire, mais en fait, ils sont opposés. Alors que les boucles s'exécutent aussi longtemps que quelque chose est vrai / valide, alors que jusqu'à ce que les boucles s'exécutent aussi longtemps que quelque chose est «pas valide / vrai encore». Souvent, ils sont interchangeables en inversant la condition.
Conclusion
J'espère que vous pouvez commencer à voir la puissance de Bash, et surtout pour, pendant que et jusqu'à ce que Bash boucle des boucles. Nous n'avons fait gratter la surface ici, et je suis peut-être de retour plus tard avec d'autres exemples avancés. En attendant, laissez-nous un commentaire sur la façon dont vous utilisez des boucles bash dans vos tâches ou scripts quotidiens. Apprécier!
Tutoriels Linux connexes:
- Boucles imbriquées dans les scripts bash
- Masterring Bash Script Loops
- Une introduction à l'automatisation Linux, des outils et des techniques
- Choses à installer sur Ubuntu 20.04
- Gestion de scripts et de processus de bash multithread au…
- Choses à faire après l'installation d'Ubuntu 20.04 Focal Fossa Linux
- Système linux hung? Comment s'échapper vers la ligne de commande et…
- Gestion de la saisie des utilisateurs dans les scripts bash
- Mint 20: Mieux que Ubuntu et Microsoft Windows?
- Choses à installer sur Ubuntu 22.04
- « Manjaro Linux Windows 10 Double démarrage
- Comment mettre à niveau Ubuntu à 20.04 LTS FOCAL FOSSA »