0. Index
- Des choses qui arrivent à la plupart des gens
- Structure d'un script
- Imprimer à l'écran
- Lire l'entrée utilisateur
- Calculs en bash
- Termes
- Boucles
- fonctions
- 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
BIN = "dossier contenant les scripts" PATH = "$ BIN $ PATH"
2. Structure d'un script
- Tête
- Définition des variables globales
- Aide
- fonctions
- 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.
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.
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"
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))
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:
- Programmation dans Bash: partie 1
- Bash: if, then, else conditions
- Vérifiez si un fichier ou un dossier existe ou non et plus avec une boucle if
- Programmation dans Bash: partie 2
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
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.
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.
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).
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.
MAGISTRAL. Je ne dis pas plus U_U
Bonjour très bon article.
Hé vous mettez pour donner des autorisations sudo + x au lieu de chmod + x
$ sudo chmod + x script.sh
(Pour être plus exact, hehe)
Ah, bravo et merci!
Très bon message, la vérité est que je vous félicite, continuez comme ça, salutations
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
MORCEAU de tutelle. Excellent et très bien expliqué.
Merci.
Excellent article sur le sujet 😉
Très intéressant et important, merci pour l'information….
À VOTRE SANTÉ !!!
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.
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!
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 😀).
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
Un très bon tutoriel de script bash!
-- 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)}' ».
À 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
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.
Excellent tutoriel, car Sysadmin connaissant les scripts dans Bash est essentiel, il est utile pour tout.
Très très bien!
Salutations!
Au cas où cela serait utile à quiconque, voici plusieurs utilisations et exemples pour créer vos propres scripts: https://github.com/reduardo7/hsabx
Très bon. De nouvelles choses à ajouter à mes scripts. Le truc encodig et le truc printf ne l'avaient pas.
Merci!!!
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 !!!!