Boucles de bash avec des exemples

Boucles de bash avec des exemples

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 et jusqu'à 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
Script bash - boucles bash avec des exemples

Exemples de boucles de bash

  1. Commençons par un base pour boucle:
    $ pour i en $ (SEQ 1 5); faire écho $ i; fait 1 2 3 4 5
    Copie

    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 du dans 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:

    $ seq 1 5 1 2 3 4 5
    Copie

    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:

    $ test de chat.txt 1 2 $ echo "$ (test de chat.txt | tête -n1) "1
    Copie

    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:

    $ si ["a" == "a"]; Puis écho "Oui!"; fi oui!
    Copie

    Remarquez comment encore le ; est avant le alors, 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 donc pour ou si doit être résilié avant la prochaine action qui est «alors» dans l'exemple de l'instruction if, et faire 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 le je variable ($ i)
    ;: Terminer la déclaration d'écho (terminer chaque action)
    fait: Indiquez que c'est la fin de notre boucle

  2. Prenons ce même exemple, mais écrivons-le différemment:
    $ pour i en 1 2 3 4 5; faire écho $ i; fait 1 2 3 4 5
    Copie

    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.

  3. Augmenter la complexité de notre boucle pour les fichiers:
    $ 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
    Copie

    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 le je variable, un fichier per / pour chaque boucle le pour 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 contiendra 1.SMS. La prochaine course $ i contiendra 2.SMS et ainsi de suite.

    Cat "$ i" | tête -N1: Ici nous prenons le $ i variable (comme nous l'avons vu 1.SMS, suivie par 2.SMS etc.) et chat ce fichier (l'afficher) et prendre la première ligne de la même tête -N1. Ainsi, 5 fois 1 est la sortie, car c'est la première ligne dans les 5 fichiers comme nous pouvons le voir depuis le précédent tête -N1 dans l'ensemble .fichiers txt.

  4. Que diriez-vous d'un très complexe maintenant?
     $ 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 ! 
    Copie

    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 le dans 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 faire Fichier Tail -N1.SMS - un sténographie que les nouveaux développeurs bash pourraient facilement manquer. En d'autres termes, ici nous une simple impression 1 (La dernière ligne en 1.txt) immédiatement suivi de 2 pour 2.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:

    $ pour je dans $ (ls *.txt 2> / dev / null); faire echo -n "$ (tail -n1 $ i)"; fait 12345 $
    Copie

    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 le fait.

    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?

  5. En utilisant une boucle de temps pour générer une chaîne aléatoire:
    $ 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
    Copie

    Qui a l'air complexe! Analyons-le pas à pas. Mais d'abord, voyons à quoi cela ressemblerait à l'intérieur d'un script bash.

  6. Exemple des mêmes fonctionnalités, implémentées dans un script bash:
    $ 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 "
    Copie
    $ 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 par Date +% 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 le COMPTER variable à 0
    Myrandom = en ligne 7: définissez le Myrandom 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'à un casser La déclaration est donnée.
    Count = $ [$ count + 1] sur la ligne 10: augmenter notre COMPTER variable par 1
    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. quand COMPTER est plus grand alors dix 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 boucle dix fois à la suite du COMPTER 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 le ALÉATOIRE la variable renvoie une variable semi-aléatoire (basée sur le Alé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 tous 1 etc. Comme le premier caractère de la sortie est toujours pris par le SED!

  7. 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 du alors que boucle sur la ligne suivante également, afin qu'il devienne inutile d'utiliser même le ; là.

    $ Cat test2.sh #!/ bin / bash pour i dans $ (seq 1 3) faire écho "… boucle… $ je…" fait
    Copie
    $ ./ 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.

  8. Enfin, jetons un coup d'œil à un bash 'jusqu'à la boucle:
    $ Nr = 0; jusqu'à [$ nr -eq 5]; faire écho "$ nr"; Nr = $ [$ nr + 1]; fait 0 1 2 3 4
    Copie

    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 notre si condition, ou mieux notre jusqu'à condition. je dis si Comme la syntaxe (et le travail) est similaire à celle de la commande de test, je.e. la commande sous-couche qui est utilisée dans si 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 variable NR atteint 5, alors le test deviendra vrai, ce qui en fait le jusqu'à 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 variable NR
    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 boucle

    Comme 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.

  9. 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