Théorie de Bash

/ bin / bash

0. Index

  1. Des choses qui arrivent à la plupart des gens
  2. Structure d'un script
  3. Imprimer à l'écran
  4. Lire l'entrée utilisateur
  5. Calculs en bash
  6. Termes
  7. Boucles
  8. fonctions
  9. getops

1. Ce qui arrive à la plupart des gens

/ bin / bash ou / bin / sh

L'une des premières choses que fait la machine lors de l'exécution de notre script est de voir avec quel shell elle doit le faire. Sur la plupart des systèmes Linux actuels / Bin / sh est un lien vers / bin / bash, mais ce n'est pas toujours le cas, par exemple dans les distributions qui utilisent busybox ils apportent Sh et généralement ils apportent aussi Frapper, mais si vous utilisez / Bin / sh, il ne fonctionnera pas avec Bash. C'est pourquoi je recommande de toujours utiliser / bin / bash.

Unicode contre ASCII

Vous êtes-vous déjà demandé pourquoi vous ne pouvez pas utiliser "¿" ou "ñ" dans vos scripts? Ou utilisez des accents? Cela peut être assez ennuyeux dans les scripts interactifs. C'est parce que le codage par défaut de Bash est ASCII, ou ce qui est le même, le jeu de caractères anglais. Pour le changer, il suffit de dire à notre script que nous voulons utiliser Unicode. Pour cela, vous devez ajouter une ligne juste après l'interpréteur de commandes:

# - * - ENCODAGE: UTF-8 - * -

Attention, il est important que cette ligne soit au début du script.

Rendre le script exécutable

C'est drôle combien de personnes exécutent les scripts avec «$ script bash.sh" au lieu de "$ ./script.sh«Après tout, c'est pour cela que nous avons défini un shell.

Pour ajouter des autorisations d'exécution, vous devez exécuter:

sudo + x script.sh
Si notre script est exécutable, nous pouvons l'ajouter à notre PATH et le rendre exécutable à partir de n'importe où / dossier sur notre ordinateur. Pour cela nous devons ajouter soit au .bashrc de notre utilisateur, soit à / etc / bashrc la ligne
BIN = "dossier contenant les scripts" PATH = "$ BIN $ PATH"
C'est une règle Bash d'écrire les noms de variables en majuscules. Beaucoup de gens ne suivent pas cette règle, mais pour les scripts longs, c'est apprécié car ils les rendent beaucoup plus lisibles

2. Structure d'un script

  1. Tête
  2. Définition des variables globales
  3. Aide
  4. fonctions
  5. Corps principal

L'en-tête est l'endroit où nous indiquons quel shell nous voulons utiliser et l'encodage. L'avantage des fonctions est de réutiliser du code qui est répété en l'écrivant une seule fois et de faciliter la compréhension du script, pour le code qui dépasse 100 lignes c'est très utile.

Pour utiliser les fonctions, elles doivent être définies avec avant le corps principal de notre script. Et si nous voulons utiliser des variables au niveau global de tous nos scripts, aussi bien dans le corps principal que dans les fonctions, il faut les définir au début de tout, juste après l'en-tête.

Enfin, il est recommandé d'écrire une fonction d'assistance lorsque notre script s'exécute mal ou avec de mauvais paramètres. Évidemment, dans ces cas, nous voulons quitter le script immédiatement, sans lire les fonctions. Pour cela, nous pouvons utiliser:

function help () {echo "" "Notre texte d'aide bien formaté." "" exit if [[-z $ 1 || $ 1 == "-h" || $ 1 == "--help"]]; alors aidez fi

Si nous ajoutons "exit" à la fonction d'aide, nous quitterons le script à chaque fois que nous exécuterons l'aide, par exemple après des messages d'erreur, etc. Nous sauvegardons quelques lignes de code.

La condition indique d'afficher l'aide à l'écran et de quitter si le script est exécuté sans paramètres ou si -h / –help est spécifié. Si vous regardez cela, c'est le comportement standard de la plupart des programmes Linux.

L'utilisation des 3 guillemets avec écho permet d'utiliser des sauts de ligne sans laisser le message s'afficher par écho. Pour les messages multilignes, il est beaucoup plus pratique d'utiliser l'écho une seule fois.

3. Imprimer à l'écran

Il existe 2 commandes principales pour imprimer à l'écran dans bash: «echo« Et »printf«. Ils sont tous les deux tout aussi rapides et font tous les deux partie de bash. La principale différence pour un débutant est que l'écho ajoute une nouvelle ligne à la fin, tandis que «printf" il ne le fait pas.

L'écho est très bon et c'est ce que la plupart des gens utilisent, cependant lors de la lecture de l'ENTREE de l'utilisateur, ou lorsque vous souhaitez imprimer des variables extraites de fichiers par traitement de texte, des choses étranges peuvent se produire. Ils sont généralement faciles à résoudre, aussi simple que de changer les guillemets doubles en guillemets simples ou vice versa, ou de retirer les références de variables des guillemets. «Écho»Fait des choses étranges aussi en fonction de la façon dont il a été compilé, si nous utilisons toujours Ubuntu ou toujours Fedora, cela ne nous affecte pas, mais si nous changeons la distribution, cela fait.

C'est pourquoi j'utilise «printf«, Ce qui ne me donne pas de maux de tête et se comporte aussi plus comme«printf»De C ou du«impression»De Python, ceci est très important si jamais vous souhaitez porter votre script vers un autre langage de programmation.

Pour une discussion plus approfondie, vous pouvez visiter cette question d'Unix et Linux sur Stack Exchange.

4. Lire l'entrée utilisateur

Tout ce que nous écrivons après le nom de notre script et avant d'appuyer sur la touche ENTER est automatiquement enregistré dans des variables spéciales. Ces variables sont du type $ X où X est un nombre.

«$0»Indique le nom de notre script et de«$1»À l'infini, tout ce que nous avons écrit plus tard est variable. Par exemple:

cat << EOF >> test.sh #! / bin / bash # - * - ENCODAGE: UTF-8 - * - printf "\ $ 0 = $ 0 \ n" printf "\ $ 1 = $ 1 \ n" printf "\ $ 2 = $ 2 \ n" EOF chmod + x script.sh ./script.sh mon fichier.txt

Nous créons un script de test, le rendons exécutable et l'exécutons avec 2 paramètres. Nous obtenons la sortie écran de:

$ 0 = ./script.sh $ 1 = mon $ 2 = fichier.txt

En utilisant des guillemets, nous aurions pu passer "mon fichier.txt" à "$ 1".

On peut aussi lire l'ENTREE d'un utilisateur avec la commande "read", indiquant directement la variable où l'on veut sauvegarder le paramètre. Par exemple:

printf "Quel est votre nom? \ n" read NAME printf "Bonjour, $ NAME. \ n"
Soyez prudent avec l'affectation des variables. "$ VAR = content" produira une erreur, aucun espace ne pourra être laissé entre le signe égal, le nom de la variable et le contenu. L'utilisation correcte est "VAR = content"

5. Calculs dans Bash

Pour cela, nous pouvons utiliser «expr«, Tant que nous n'avons pas besoin de faire des calculs complexes. Il faut noter deux choses, la première est que «expr»N'admet que des nombres entiers, la seconde est que la division renvoie le résultat entier, pour voir le reste on peut utiliser«%«.

Habituellement, nous voulons affecter le résultat de expr à une variable. Nous pouvons le faire de deux manières:

VAR2 = `expr $ VAR1 / 10` VAR2 = $ (expr $ VAR1 / 100)

Vous pouvez également ignorer «expr»En utilisant des doubles parenthèses:

VAR2 = $ (($ VAR1 / 100))
Pour une explication plus détaillée de «expr»Ou une alternative qui utilise des nombres entiers, vous pouvez regarder cette entrée KZKG ^ gaara.

6 Conditions

Il a déjà été écrit de manière très détaillée sur «if«,«d'autre«,«Elif»Et les conditions. Vous pouvez en savoir plus sur:

Je veux juste souligner la différence entre l'utilisation de simples crochets, «[]«, Et doubles crochets,«[[]]«, Pour les conditions. Avec les doubles crochets, nous pouvons utiliser des conditions supplémentaires:

  • «&&"Pour et
  • «||»Pour ou

Utiliser "&&« Et »||»Avec de simples crochets, chaque partie doit être séparée entre crochets séparés. L'exemple utilisé pour la partie du script qui cherche à voir si l'aide doit être exécutée serait:

si [-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "--help"]]; alors aidez fi

Cela nous évite également d'avoir à écrire les noms de variables entre guillemets pour éviter les erreurs. Par exemple:

si [$ 1 = 1]; then printf "Le paramètre est égal à 1."; fi si ["$ 1" = 1]; then printf "Le paramètre est égal à 1."; fi si [[$ 1 = 1]]; then printf "Le paramètre est égal à 1."; Fi

Si script.sh est exécuté sans aucun paramètre, le premier cas donnerait une erreur:

bash: [: =: opérateur unaire attendu
En bash, "=" et "==" sont tous deux interprétés de la même manière. Cela ne se produit pas dans d'autres langages de programmation où "=" est utilisé uniquement pour affecter des variables.

Ce dont on n'a pas parlé, c'est «maisons«, Utilisé pour simplifier«if«. Commençons par le début, quand on n'a pas de «if»Tout le code sera exécuté. Si nous ajoutons une condition «if»Nous aurons deux cas, l'un dans lequel le bloc de code à l'intérieur du«if»Et l'autre cas où ce bloc n'est pas exécuté.

Si nous ajoutons un «d'autre«Nous aurons également deux cas, mais ces deux cas sont différents des précédents. Parce que maintenant, il y aura deux blocs de code conditionnel, A et B, et un bloc C, qui est le reste du programme. A ou B sera exécuté, et C. Dans le cas précédent, c'était A et C ou seulement C.

Pour éviter d'écrire des conditions «sinon" dans "d'autre»Et pour simplifier la lecture du code, il a été créé«Elif«. Lorsque nous avons de nombreuses conditions qui dépendent de la précédente, par exemple la plage de nombres ou le type:

VAR1 = $ 1 si [[$ VAR1 = 1]]; puis printf "1 \ n" elif [[$ VAR1 = 2]]; puis printf "2 \ n" elif [[$ VAR1 = 3]]; puis printf "3 \ n" else printf "aucun \ n" fi

Dans le cas du dernier «Elif»De nombreuses conditions seront lues. Avec le cas, ce processus est simplifié:

VAR1 = $ 1 cas $ VAR dans 1) printf "1 \ n" ;; 2) printf "2 \ n" ;; 3 | 4) printf "3 ou 4, cela dépend \ n" ;; *) printf "aucun \ n" ;; Cette c

Une variable sera lue, dans ce cas VAR1, et il sera vérifié si elle équivaut à l'un des cas, sinon, le cas par défaut "*" sera exécuté. Les doubles points-virgules équivalent à «pause", Ils disent"maisons»Cela doit prendre fin.

«Boitier»Peut également être utilisé comme séquence de«if«, Pour cela il faut utiliser« ;; & »(continuer) au lieu de« ;; » (Arrêtez).

7. Boucles

Très peu de boucles sont connues dans n'importe quel langage de programmation. Dans Bash, ils sont «tout en«,«jusqu'à« Et »en«. Il a déjà été écrit dans le blog à ce sujet:

Il existe deux types de boucles «en«, Ceux qui sont du type«$ pour VAR à LOQUESEA»Et que sont de type C«$ pour ((I = 0; I <= 10; I ++))«. Le deuxième type de boucles «en»Sont très utiles, il comporte 3 parties au début de la boucle:

  • Déclaration et déclenchement des variables (dans ce cas, une variable auxiliaire "I = 0").
  • Condition d'exécution (jusqu'à ce que I soit inférieur ou égal à 10).
  • Augmentation de la variable auxiliaire

À mon avis, c'est la boucle la plus puissante de toutes. Un exemple, qui imprime tous les nombres de 0 à 10, inclus:

#! / bin / bash pour ((I = 0; I <= 10; I ++)); faire printf "$ I \ n" terminé

8. Fonctions

Il y a des choses que Bash ne nous permet pas de faire, non? À première vue, les fonctions bash vous empêchent de faire 3 choses: déclarer des variables locales dans les fonctions, passer des paramètres aux fonctions et renvoyer des paramètres. Tout a une solution.

Ne faites rien comme:

#! / bin / bash VAR = 1 printc "$ VAR \ n" function bonjour () {VAR = 2 printf "$ VAR \ n"} bonjour printf "$ VAR \ n"

Ceci s'imprime sur les écrans 1, 2 et 2.

Pour déclarer des variables locales, ajoutez «locales»Lors de la déclaration:

#! / bin / bash VAR = 1 printf "$ VAR1 \ n" function foo () {local VAR1 = 2 printf "$ VAR1 \ n"} printf "$ VAR1 \ n" foo printf "$ VAR1 \ n"

Cela imprime 1, 1, 2, 1 à l'écran.

Comment passez-vous des paramètres à une fonction?

#! / bin / bash # - * - ENCODAGE: UTF-8 - * - function hello () {printf "Hello $ 1 \ n"}

printf "Quel est votre nom? \ n"
lire VAR1
bonjour $ VAR1

Comment les paramètres sont-ils renvoyés?

#! / bin / bash # - * - ENCODAGE: UTF-8 - * - function hello () {printf "Hello holita"} printf "Comment tu t'appelles? \ n" read VAR1 VAR1 = $ (bonjour) # ICI C'EST printf "$ VAR1 $ VAR2 \ n"

Comme vous pouvez le voir, cela présente deux inconvénients, vous ne pouvez renvoyer qu'un seul paramètre, qui peut être un vecteur 😀, et si vous souhaitez renvoyer un paramètre, vous ne pouvez plus imprimer à l'écran à partir de cette fonction.

Vous pouvez trouver plus d’informations sur les fonctions sur [url=https://blog.desdelinux.net/programando-en-bash-parte-3/]cet article de Usemoslinux[/url].

9. Getops

Une des dernières choses que vous devez savoir sur Bash pour créer des scripts complexes est «attrape«. Il est utilisé pour transmettre des options au script quel que soit l'ordre. Le seul inconvénient est qu'il n'affecte que les options courtes:

#! / bin / bash # - * - ENCODAGE: UTF-8 - * - VARC = 0 function help () {printf "Help message \ n" exit} if [[-z $ 1]]; puis aidez fi pendant getopts: ha: b: c OPT; faire le cas $ OPT dans h) help ;; :) Aidez-moi ;; a) VARA = $ OPTARG ;; b) VARB = $ OPTARG ;; c) VARC = 1 ;; \?) Aidez-moi ;; esac done # Bloc principal du script qui # fait des choses avec VARA, VARB et VARC

«getops»Lit les options une par une, donc une boucle est nécessaire.

Il existe 2 types d'options qui peuvent être passées en utilisant «getops":

  • Paramètres appelés indicateurs, dans ce cas -c ou -h. Ils sont spécifiés avec la lettre que nous voulons utiliser. Ce sont comme des variables booléennes, «oui»(Sont) ou«non" (ne sont pas).
  • Paramètres avec arguments associés, -a n'importe quoi, -b n'importe quoi. Ils sont spécifiés avec la lettre que nous voulons avec un deux-points ci-dessous. L'argument est stocké dans OPTARG (ce nom n'est pas modifiable).
Les points doubles initiaux ne doivent montrer aucune erreur.

Que fait ce script?

Affiche le message d'aide lorsqu'aucune option n'est passée, lorsque le paramètre "-h" est passé, lorsqu'un paramètre non valide est passé (par exemple "-x", cela se fait par "\?") Ou lorsqu'un paramètre valide sans argument (":"). Dans le reste des cas, il enregistre la présence de "-c" comme 1 dans VARC, et les valeurs passées avec "-a" et "-b" dans VARA et VARB.


Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont marqués avec *

*

*

  1. Responsable des données: Miguel Ángel Gatón
  2. Finalité des données: Contrôle du SPAM, gestion des commentaires.
  3. Légitimation: votre consentement
  4. Communication des données: Les données ne seront pas communiquées à des tiers sauf obligation légale.
  5. Stockage des données: base de données hébergée par Occentus Networks (EU)
  6. Droits: à tout moment, vous pouvez limiter, récupérer et supprimer vos informations.

  1.   animé dit

    MAGISTRAL. Je ne dis pas plus U_U

  2.   Miguel dit

    Bonjour très bon article.
    Hé vous mettez pour donner des autorisations sudo + x au lieu de chmod + x

    1.    Henri dit

      $ sudo chmod + x script.sh
      (Pour être plus exact, hehe)

      Ah, bravo et merci!

  3.   pétard dit

    Très bon message, la vérité est que je vous félicite, continuez comme ça, salutations

  4.   Gustavo dit

    Et si vous voulez que le script soit visible lors de son exécution, pas à pas, en voyant par exemple comment les variables, les conditions et tout se comportent, vous pouvez utiliser:

    script sh -x

    salutations

  5.   Dago dit

    MORCEAU de tutelle. Excellent et très bien expliqué.
    Merci.

  6.   Gabriel dit

    Excellent article sur le sujet 😉

  7.   Mario Guillermo Zavala Silva dit

    Très intéressant et important, merci pour l'information….
    À VOTRE SANTÉ !!!

  8.   Pasdebrooklyn dit

    Merci à tous pour vos félicitations, quant à la commande Miguel, il ne me laisse pas modifier l'entrée une fois qu'elle est publiée. Il devra faire elav j'imagine.

  9.   Adrian dit

    Très bonnes!

    Tout d'abord je voulais vous féliciter pour le post, je l'ai trouvé facile à comprendre et cela aide vraiment à suivre les directives pour bien programmer en bash, en particulier pour les personnes qui commencent à programmer.

    Cependant, j'ai trouvé quelques détails qui, à mon avis, devraient être corrigés.

    Premièrement: dans la section «2. STRUCTURE D'UN SCRIPT »la fonction n'est pas fermée, ce qui posera des problèmes lors de son exécution dans un script.
    La solution serait de lui ajouter une accolade fermante juste après la commande "exit".

    Deuxièmement: dans la section «4. LISEZ L'ENTREE UTILISATEUR »vous affirmez que les paramètres que l'utilisateur peut saisir vont de 0 $ à l'infini, cependant,« bash »n'interprétera que de 0 $ à 9 $, puisque 10 $ serait égal à 1 $ + 0.
    Pour résoudre ce problème, vous pouvez utiliser la commande "shift" pour récupérer les variables suivantes. Ou spécifiez la variable entre accolades "$ {10}", de sorte que bash prenne les valeurs ensemble, pas comme $ 1 + 0.

    Sans plus tarder, salutations!

    1.    Pasdebrooklyn dit

      Merci pour ton commentaire. Il a totalement échoué à expliquer l'utilisation correcte de exit, à la fois dans le script et dans les fonctions. Quant à $ {10} je n'ai jamais autant légué, donc je n'ai pas rencontré ce problème, il est bon de savoir qu'il y a une solution pour ça (j'ai déjà barré la nouvelle chose apprise aujourd'hui 😀).

  10.   Chanio dit

    Merci beaucoup pour l'article! Certaines choses que vous mentionnez manquent encore de clarification. Par exemple, getops.
    Dans la partie des sorties écran, vous deviez mentionner le chat que vous mentionnez plus tard ...
    chat <
    ***************************************
    * CE FORMULAIRE EST TRÈS EXPRESSIF *
    ***************************************
    EOF

    Dans votre exemple:
    cat << EOF >> test.sh
    Il faut mentionner deux choses ... >> c'est 'append' c'est-à-dire que si vous répétez la même commande, vous aurez tout le script en double ... Vous ne devriez en utiliser qu'un ...
    cat << EOF> script.sh
    Oui, il devrait également être appelé script.sh
    Puis dans
    si [-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "–help"]]; puis
    aider
    fi

    Je pense que ça devrait être écrit ...
    si [[-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "–help"]]; puis
    ...

    Il y a beaucoup plus à découvrir de BASH.
    Pourriez-vous l'intituler "BASICS"? 🙂
    Par exemple, le paramètre «testeurs» comme -z pour voir s'ils sont vides, ou -f pour savoir s'il existe en tant que fichier.

    Merci encore pour vos efforts.
    alberto

  11.   clown_eriol dit

    Un très bon tutoriel de script bash!

  12.   OCZ dit

    -- ENCODAGE: UTF-8 --

    C'est la première fois que je vois cette ligne pour définir le codage des caractères dans un script bash. Cela me semble plus Python que Bash. Est-ce vraiment nécessaire? J'ai cherché une référence sur Google mais je ne trouve rien, avez-vous un lien sous la main qui parle de ce sujet? Plus précisément sur la pertinence de cette ligne.

    À mon avis, pour écrire des scripts dans Bash en utilisant UTF-8, il suffit de sauvegarder le fichier texte en tant que tel (sans BOM) et d'avoir certaines variables d'environnement, (LANG et LC_ *), correctement définies.
    Ensuite, évidemment, il est nécessaire que les commandes exécutées soient préparées pour des encodages autres que ASCII. Par exemple, si nous voulons passer en majuscules, cela ne semble pas fonctionner:
    «Echo áéíóú | tr az AZ »
    o:
    «Echo áéíóú | tr [: inférieur:] [: supérieur:] »
    et il vaut mieux utiliser:
    «Echo áéíóú | awk '{print toupper ($ 0)}' ».

    1.    Pasdebrooklyn dit

      À propos de "codage»A déjà été mentionné dans ce blog:

      Bash: comment rendre un script exécutable
      Script de l'utilitaire de post-installation

    2.    borriquito comme toi dit

      Quelqu'un m'a corrigé, mais cette ligne d'encodage (# -- ENCODAGE: UTF-8 --) Cela n'a rien à voir avec bash ou le shell: c'est une ligne de commentaire (commence par #) et sert à dire à l'EDITEUR que nous utilisons pour écrire le script (vim, emacs ...) l'encodage du fichier.

      En fait, bash ne voit pas une telle ligne, car c'est une ligne de commentaire.

  13.   Jorge-1987 dit

    Excellent tutoriel, car Sysadmin connaissant les scripts dans Bash est essentiel, il est utile pour tout.

    Très très bien!

    Salutations!

  14.   Edouard Cuomo dit

    Au cas où cela serait utile à quiconque, voici plusieurs utilisations et exemples pour créer vos propres scripts: https://github.com/reduardo7/hsabx

  15.   Noir Lito dit

    Très bon. De nouvelles choses à ajouter à mes scripts. Le truc encodig et le truc printf ne l'avaient pas.
    Merci!!!

  16.   xxxtonixxx dit

    Tellement bon article! Je garde celui-ci pour les favoris, ce serait bien de corriger ce qui ne va pas et même de l'élargir avec plus de contenu. Une salve d'applaudissements pour toutes ces infos !!!!