Qu’est-ce que le Shell Bash Scripting ?
Durée : 1 h
Prérequis : Un minimum de connaissances concernant les commandes d’administration de base sera nécessaire.
Environnement de travail : Disposer d’un ordinateur sous Linux (environnement virtualisé ou non).
Contexte
Parce que certaines tâches simples sont indispensables, mais chronophages, parce qu’un administrateur ne peut pas se déplacer sur chacun des serveurs de l’entreprise, parce que les conséquences d’un oubli peuvent être catastrophiques, il est indispensable aujourd’hui, pour tout administrateur, d’être en mesure d’automatiser certaines tâches simples. Ce sont ces bases que vous allez aborder dans ce cours.
Le Shell
Sous UNIX, le « Shell » est un programme qui facilite l’interaction entre un utilisateur et le système d’exploitation. Le Shell est un interpréteur de commande, c’est-à-dire que chacune des commandes saisies (contenues dans un fichier ou saisies directement dans le terminal) va être vérifiée puis appliquée. La vérification se fait selon une syntaxe particulière. En cas de syntaxe incorrecte, la commande ne sera pas exécutée. Il existe de nombreux Shell (par exemple csh, tcsh, sh bash, dash, ksh, zsh).
Concernant les systèmes GNU/Linux, le Shell utilisé par défaut est bash (ou Bourne Again Shell), mais d’autres Shell peuvent tout aussi bien être utilisés et sont également préinstallés sur les distributions Linux
La commande « echo $SHELL » affiche la valeur d’environnement Shell, c’est-à-dire le type de Shell défini par défaut pour l’utilisateur.
Afin de connaître tous les Shell disponibles sur votre système, saisissez la commande dans le terminal suivante :
cat /etc/shells
Le Shell Scripting
Un fichier de script se construit de la manière suivante :
Le « Shebang » se retrouve en tête du fichier texte de script et indique au système d’exploitation qu’il s’agit d’un fichier de script. Il s’écrit sous la forme :
# !
Sur la même ligne, à la suite des deux premiers caractères, il est indispensable de préciser l’interpréteur qui sera utilisé.
Exemple
Pour un script en bash, il vous faudra indiquer, en tête du fichier, la ligne suivante :
# !/bin/bash
Pour expliquer les différentes fonctions qui s'exécutent, vous devez commenter votre script. Tout ce qui suit le signe « # » est assimilé à du commentaire et ne sera donc pas interprété :
# ceci est une ligne de commentaire
Une fois votre fichier de script rédigé et enregistré, vous devez lui donner des droits d’exécution (chmod + x) avant de pouvoir le lancer. Vous allez maintenant mettre cette partie en pratique.
Mise en pratique d'écriture et d'exécution d'un script
Étape 1 : Après avoir ouvert votre terminal (via Putty à distance, par exemple), déplacez-vous à l’endroit où vous souhaitez créer votre script.
cd /chemin/de/destination
Étape 2 : Ouvrez votre éditeur de texte et attribuez un nom à votre fichier, sans oublier d’y ajouter l’extension « .sh ».
nano nom_script.sh
N’oubliez pas de sauvegarder en quittant, pour générer le fichier.
L'extension de fichier .sh
0 seconds of 4 minutes, 8 secondsVolume 100%
Étape 3 : Rendez le script exécutable afin de pouvoir le lancer :
chmod +x nom_script.sh
Étape 4 : Lancez l’exécution du script en saisissant l’une ou l’autre des commandes suivantes :
sh nom_script.sh
./nom_script.sh
Le planificateur de tâches
Une fois votre script créé, testé et fonctionnel, vous pouvez automatiser les tâches qui peuvent l’être, grâce au planificateur de tâches : le cron.
Les différentes options ajoutées à crontab vous permettent d’administrer le fichier. Voici quelques commandes :
crontab –l : permet d’afficher la liste des actions planifiées.
crontab –r: permet de supprimer toutes les actions planifiées.
crontab –e: permet d’éditer et de modifier les actions planifiées.
C’est cette dernière commande, « crontab –e », qui va vous permettre de configurer la planification de votre script. Cependant, ce fichier doit respecter une certaine syntaxe qui se présente sous la forme suivante :
minutes heures jour_du_mois mois jour_de_la_semaine utilisateur tâche > log
Les minutes sont indiquées par des nombres de 00 à 59
Les heures sont exprimées par des nombres de 00 à 23
Les jours du mois sont exprimés de 01 à 31
Les mois sont indiqués, soit avec des nombres de 01 à 12, ou avec les 3 premières lettres du mois en anglais (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec)
Les jours de la semaine sont exprimés de 1 à 7 ou avec les 3 premières lettres du jour en anglais (mon, tue, wed, thu, fri, sat, sun)
L’utilisateur est à spécifier, le cas échéant, si la tâche doit être effectuée par un utilisateur particulier
La tâche correspond à la commande que vous voulez exécuter
> log correspond à la sortie vers un fichier log spécifique, si vous le souhaitez, sinon un mail sera envoyé à l’utilisateur local.
Concernant les unités de temps, les récurrences et intervalles sont exprimés par une syntaxe particulière :
Le tiret (-) |
1-10 |
Détermine une plage de valeur, ici de 1 à 10 |
La virgule (,) |
1,2,3 |
Spécifie une liste de valeurs, ici 1, 2 et 3 |
L’astérisque (*) |
* |
Équivaut à toutes les valeurs |
Le slash (/) |
/ |
Ignore un nombre donné de valeurs |
Exemple
« * » correspond à toutes les valeurs et « /6 » signifie la première valeur (0) puis la 7ème valeur (6), donc « */6 » sur le 1er champ correspondrait à une fréquence de 6min.
Exemple
L’exécution d’une sauvegarde quotidienne à 23 h 00 s’écrit :
00 23 * * * /root/scripts/sauvegarde.sh
Le script de sauvegarde sera lancé à 23h00, tous les jours de chaque mois.
L’exécution d’une synchronisation récurrente quotidienne (4 h) s’écrit :
00 */4 * * * /root/scripts/synchronisation-ftp.sh
Le script de synchronisation FTP sera exécuté toutes les 4 h 00, tous les jours de chaque mois.
La rédaction d’un script
Les caractères spéciaux
Certains caractères ont une signification particulière pour le Shell et sont interprétés : il s’agit des caractères spéciaux. Pour les utiliser en tant que caractères dans une commande, il faut les « échapper », concrètement il faut les faire précéder du caractère « \ » afin que le Shell ne les interprète pas.
Soyez vigilant, afin d’éviter de nombreuses erreurs.
Les caractères spéciaux sont les suivants :
?
*
&
< >
‘ ’
~
“ ”
^
{ }
[ ]
;
\
#
!
$
espace
Les commandes composées
Pour avoir une meilleure visibilité dans un script, ou pour plus de précision, l’utilisation de commandes composées est recommandée.
En voici quelques-unes :
Deux commandes séparées par un point-virgule« ; » vont tout simplement s’enchainer comme si elles étaient écrites sur deux lignes différentes.
action_1 ; action_2
Deux commandes séparées par un pipe « | » permettent d’appliquer la deuxième commande sur la base du résultat de la première.
action_1 | action_2
Deux commandes séparées par deux pipes « || » signifie que la seconde commande est effectuée uniquement dans le cas où la première est en échec.
action_1 || action_2
Deux commandes séparées par « && » signifie que la seconde commande est effectuée uniquement dans le cas où la première est réussie.
action_1 && action_2
Les commandes de base d’un script Bash : les variables
Elles peuvent contenir n’importe quelle valeur (du texte, un chemin, une commande, etc.). Il n’est pas nécessaire de spécifier le type de variable dont il s’agit. Pour vous y retrouver dans un script, il vaut mieux que le nom de variable soit explicite.
Pour déclarer une variable, il faut indiquer son nom et le faire suivre du signe « = » (égal) :
var= ‘il faut mettre des guillemets ou des apostrophes si il y a des espaces’
Pour appeler une variable, il faut indiquer son nom précédé du signe « $ » (sans espace) :
$var
Les commandes de base d’un script Bash : les conditions
if / elif / else :
« if » signifie que si la condition est vraie, alors (then) il faut faire telle ou/et telle action.
« fi » termine la structure.
La syntaxe est :
if condition ; then
actions;
fi
« if » peut-être associé à « else », ce qui signifie que si la condition est vraie, alors il faut faire telle ou/et telle action et sinon (else), il faut en faire d’autres.
La syntaxe est :
if condition ; then
actions;
else
actions;
fi
La structure peut également être complétée par « elif », que l’on pourrait traduire par « sinon si » : si la condition1 est vraie, alors faire 1 sinon si la condition2 est vraie, alors faire 2 et sinon faire 3.
La syntaxe est :
if condition ; then
actions;
elif condition2 ; then
actions;
else
actions;
fi
case :
« case » signifie, dans chacun des cas suivants, effectuer la commande ou l’action décrite à la suite, ce qui permet d’adapter la commande à chaque situation.
Par exemple, vous souhaitez vérifier l’existence d’un fichier /home/studi/studi.txt, vous pouvez, dans le cas où le fichier existe, demander l’affichage d’un texte spécifiant « le fichier existe » et, dans le cas où le fichier n’existe pas, saisir une commande pour le créer. Mis en application, cela donnerait la syntaxe ci-dessous :
Creation script
find /home/studi/studi.txt
case $? in
1)echo “le fichier studi.txt n’existait pas et je viens de le créer” ; touch /home/studi/studi.txt;;
0)echo “le fichier studi.txt existe”;;
esac
Comme vous pouvez le constater, chaque cas est suivi d’une parenthèse fermée « ) » (sans espace).
L’action est indiquée derrière un espace et se termine par deux points-virgules « ;; ».
La fin de cette structure est « esac »
La syntaxe est :
case « valeur » in
cas1) action1;;
cas2) action2;;
cas3) action3;;
esac
Les commandes de base d’un script Bash : les boucles
for :
Il s’agit d’une boucle. Pour chaque élément défini dans la variable, un certain nombre d’actions vont être définies. La fin de la boucle est matérialisée par « done ». La boucle recommencera jusqu’à l’épuisement des différents éléments déclarés.
La syntaxe est :
for chaque_élément in $liste ; do
Actions_à_faire ;
done
while :
Il s’agit d’une boucle. Celle-ci va être exécutée tant que l’argument est vrai.
Un certain nombre d’actions vont être définies. La fin de la boucle est matérialisée par « done ».
La syntaxe est :
while test ; do
Actions_à_faire_1
Action_à_faire_2 ;
done
L’inverse de cette boucle est « until », la boucle sera exécutée jusqu’à ce que l’argument soit vrai. La syntaxe est la même :
until test ; do
Actions_à_faire_1
Action_à_faire_2 ;
done
Les bonnes pratiques pour écrire un script
Bien que l’écriture d’un script puisse paraître angoissante au premier abord, avec un peu de méthodologie, vous vous apercevrez que ce n’est pas si difficile que cela.
Pour commencer, pas de précipitation. Ouvrez votre logiciel de traitement de texte préféré, ou munissez-vous d’une feuille et d’un crayon, puis définissez concrètement et précisément ce que vous souhaitez que votre script réalise.
Ensuite, prenez le temps de détailler les différentes étapes qui doivent être exécutées.
Exemple
Vous devez expliquer à quelqu’un qui n’a jamais été confronté à de la technologie, comment utiliser un lecteur DVD. Si vous vous contentez de lui dire : « C’est facile, les différentes étapes à suivre sont : ouvrez le tiroir du lecteur, puis insérez le DVD, ensuite fermez le tiroir, allumez la télé, il ne vous reste plus qu’à vous installer dans le canapé pour profiter du film », il y a peu de chance que le résultat escompté soit obtenu.
Très probablement, si déjà le tiroir du lecteur s’ouvre, il y a peu de chance que les autres étapes s'enchaînent tel que vous l’avez imaginé… question d’interprétation.
A contrario, si vous détaillez les manipulations à effectuer de manière plus précise, vous pourriez dire : « mais non, la technologie n’est pas indomptable. Reprenons étape par étape… Tout d’abord, il faut allumer le lecteur DVD avec le bouton situé en haut à droite du lecteur et représentant un cercle surmonté (à 12h) d’un trait vertical, puis appuyez sur le bouton d’ouverture représentant un trait droit surmonté d’une flèche pointe vers le haut. Ensuite, insérez le disque, texte vers le haut et donc, piste vers le bas, refermez le lecteur (bouton d’ouverture/fermeture trait droit, flèche vers le haut) puis allumez la télé, en sélectionnant la bonne chaine (bouton source ou chaîne auxiliaire) » … jusqu’à arriver au terme des différentes étapes.
Tout comme l’individu hermétique à la technologie, le Shell est indomptable, si vous ne respectez pas la bonne syntaxe. Bien que sans conséquence fâcheuse, l’erreur ne donnera aucun résultat…
Maintenant que vous savez détailler chacune des étapes :
Définissez les variables que vous allez utiliser.
Recherchez les commandes vous permettant d’accéder au résultat attendu à chaque étape.
Testez chacune de vos commandes.
Affinez, si nécessaire, à l’aide de filtres ou de commandes composées.
Le résultat obtenu est enfin celui que vous souhaitiez pour une commande unique. Pour vous éviter de réitérer l’opération régulièrement, automatisez et donc adaptez votre script pour le rendre efficient dans d’autres situations.
Vous pouvez désormais monter votre script avec des variables, boucles, conditions, en fonction de vos besoins.
Testez encore, avec plusieurs configurations.
Vérifiez les messages d’erreurs et corrigez votre script.
Et surtout, à chaque étape, commentez votre script, ajoutez des lignes autant que nécessaires. Vous devez vous souvenir de ce que vous avez voulu faire pour pouvoir faire évoluer votre script, et n’importe quel administrateur devrait pouvoir comprendre quels étaient vos objectifs.
Commentez, commentez, commentez, etc.
Un exemple de script
Ici, il s’agit d’un script d’automatisation de sauvegarde :
#!/bin/bash
dayJ=$(date +%Y-%m-%d)
« dayJ » est la définition de la variable de la date du jour (sous le format yy/mm/dd).
« # » variable répertoire de sauvegarde avec nom date du jour.
pathsave=/tmp/backup_$dayJ
« pathsave » correspond à la définition de la variable indiquant le chemin de sauvegarde auquel sera ajouté la date de la sauvegarde (rappel de la variable précédente), ici /tmp/backup_yy/mm/dd.
/bin/mkdir $pathsave
Une fois les variables définies, le script va permettre de créer le dossier de sauvegarde dont le chemin est défini par la variable « pathsave ».
« # » permet de créer une archive du fichier à sauvegarder avec nom du fichier + date du jour.
/bin/tar -czvf $pathsave/fichierasauvegarder_$dayJ.tar.gz /tmp/fichierasauvegarder
Cette dernière ligne du script crée une archive de « fichierasauvegarder » qui portera le nom du fichier+datedujour.
Dans cet exemple, le répertoire utilisé est « /tmp ». En entreprise, il vous faudra bien entendu personnaliser le répertoire de sauvegarde et, idéalement, favoriser un autre point de montage pour une question évidente de sécurité. N’oubliez pas de configurer l’automatisation dans le cron.