Activité Automatiser des tâches avec Bash

Consigne

Suivez les instructions ci-après et effectuez les tâches demandées.

Situation

Dans le cadre du développement d’application web, vous devez recréer la base de données de votre environnement de développement à chaque modification du schéma. Vous devez pour cela répéter un certain nombre de commandes : supprimer la base de données existante, créer la nouvelle base de données et charger les données de test.

Objectifs

À la fin de ce travail, vous devez :

  1. Connaître les commandes Bash pour la manipulation des fichiers et des répertoires (cd, ls, pwd, touch, cat, less, head, tail, mkdir, rm, cp, mv, find).
  2. Connaître les commandes Bash pour modifier le propriétaire et les permissions d’un fichier (chown, chmod)
  3. Connaître les commandes Bash permettant de lire et d’écrire dans la console (read, echo, printf).
  4. Connaître la notion de variable d’environnement.
  5. Connaître la différence entre « exécuter un script » et « sourcer un script ».
  6. Être capable d’utiliser des commandes et des variables pour réaliser un script.
  7. Être capable d’effectuer une action de manière conditionnelle à l’aide de l’instruction if-then-else.
  8. Être capable de définir et d’‘utiliser des variables d’environnements (export)

Résultat attendu

  • Un bref rapport qui décrit votre travail et votre démarche.
  • Votre script bash.

Ressources

Documents :

Logiciel :

  • Visual Studio Code

Matériel :

  • Un serveur Linux svr-m140-###-sql.lab.epai-ict.ch

Mise en route

Qu’est-ce qu’un script ?

Un script est un programme écrit dans un langage de programmation (python, ruby, etc.) ou avec un langage de commande (sh, bash, powershell, etc.). Même si l’on préfère généralement écrire un script avec un langage de programmation interprété ou un langage de commande, ce qui distingue un script, ce n’est pas tant le langage que l’environnement d’exécution :

  • Pour un script : l’environnement d’exécution est un programme qui sert en premier lieu, à autre chose qu’à exécuter des programmes. Cela peut être, par exemple, un shell, un serveur apache (httpd), une suite bureautique, un programme de CAD, etc.

  • Pour un programme : l’environnement d’exécution sert en tout premier lieu à exécuter des programmes. Cela peut être, par exemple, le système d’exploitation lui-même, le JRE (Java Runtime Environment), le CLR (Common Language Runtime) de dotNet, l’interpréteur Python, etc.

Dans le cas d’un script bash, le programme est le shell Bash qui sert, en premier lieu, d’interface utilisateur·rice pour le système d’exploitation. Dans le cas des programmes que vous avez écrits en Java, l’environnement d’exécution est le JRE dont la seule raison d’être est d’exécuter des programmes en Java.

Créer un script Bash

Un script bash est simplement un fichier de texte dans lequel on écrit une commande par ligne et éventuellement des commentaires en commençant une ligne avec le signe # (dièse ou hastag).

Bash est un shell, c’est-à-dire un interpréteur de commandes pour le système d’exploitation. Le fait qu’il s’agisse d’une interface en ligne de commande (CLI) qui reçoit des commandes sur l’entrée standard (stdin), le rend automatiquement automatisable. En effet, même si Bash ne savait interpréter directement le contenu d’un fichier, on pourrait lui envoyer des commandes en provenance d’un fichier en effectuant une redirection de son entrée standard sur ce fichier. Par exemple :

1
bash < ./mon_cript.sh
Fig. 1 – Exécuter des commandes avec une redirection de l'entrée-standard

Cette manière de faire fonctionne pour n’importe quel programme avec une interface en ligne de commande (CLI). Si votre programme en Java attend trois paramètres de type float, vous pouvez écrire trois nombres de type float séparés par des retours à la ligne dans un fichier et rediriger l’entrée standard du programme vers ce fichier.

Toutefois, le programme bash est aussi un interpréteur pour le langage de commande Bash. En plus des commandes que l’on utilise couramment de manière interactive, le langage de commande dispose de structures de choix et de structures de boucle qui en font des langages de programmation complets, dans le sens où il pourrait être utilisé pour réaliser n’importe quel programme, même si certaines limitations font qu’il ne serait certainement ni le premier ni même le second choix pour la réalisation d’une application.

Pour exécuter un script écrit en bash, il suffit de passer le fichier du script à l’interpréteur Bash, exactement comme on le ferait avec un programme Python ou Ruby.

1
bash ./mon_cript.sh
Fig. 2 – Passer un script à l'interpréteur bash (sans redirection)

Enfin, il est possible de transformer un fichier de script en un fichier exécutable en ajoutant, à la toute première ligne, un « shebang » suivi du chemin de l’interpréteur. Pour un script Bash, cela donne la ligne suivante :

1
2
3
4
#! /bin/bash

# Affiche le contenu du répertoire de travail.
ls .
Fig. 3 – Shebang pour un script Bash

Il faut ensuite ajouter la permission d’exécution de ce fichier à l’utilisateur. Comme vous en êtes le propriétaire, il suffit d’ajouter la permission au propriétaire du fichier avec la commande suivante :

1
chmod +x ./mon_script
Fig. 4 – Shebang pour un script Bash

Lorsque c’est fait, vous pouvez lancez l’exécution de votre script en indiquant simplement son chemin :

1
./mon_script
Fig. 5 – Lancement du fichier exécutable

Variable

De manière générale, pour utiliser une variable, il faut la définir. Définir une variable consiste essentiellement à lui donner une valeur. En Bash, on définit une variable de la manière suivante :

1
ma_variable="ma valeur de type chaîne"
Fig. 6 – Définir une variable

La définition d’une variable en bash doit suivre les règles suivantes :

  • Le nom de la variable est un identificateur, qui doit commencer par une lettre, n’être composé que de lettre sans accents et de chiffre, et ne pas contenir d’espace.
  • Le signe égal = doit suivre immédiatement le nom de la variable, sans espace.
  • La valeur doit être spécifiée immédiatement après le signe égal. Si la valeur est constituée d’une suite de caractère sans espace (un identifiant ou un nombre, par exemple), elle peut être écrite directement. Sinon, la valeur doit être écrite entre guillemets (double quotes) ou entre apostrophes (single quotes).

Pour écrire le contenu d’une variable dans la sortie standard (stdout), on utilise la commande echo. Pour référencer une variable, c’est-à-dire pour utiliser sa valeur, on fait précéder le nom de la variable par le signe $ (dollard).

1
echo $ma_variable
Fig. 7 – afficher la valeur une variable dans la sortie standard

Pour écrire le contenu d’une variable dans la sortie d’erreur standard (stderr), on utilise la commande echo de la même que pour écire dans la sortie standard (stdout), mais on redirige la sortie de la commande dans la sortie d’erreur standard.

1
echo $ma_variable 1>&2
Fig. 7 – afficher la valeur une variable dans la sortie d'erreur standard

La combinaison 1>&2 signifie que l’on redirige le descripteur de fichier numéro 1 (stdout) dans le fichier référencé par le descripteur numéro 2 (stderr). Le signe & devant un descripteur de fichier indique que l’on référence le fichier que représente le descripteur. On peut utiliser cette technique pour afficher un message d’erreur.

Pour définir une variable avec une valeur qui provient de l’entrée standard (stdin), on peut utiliser la commande read. Par défaut, cette commande n’affiche rien et attend jusqu’à ce qu’elle ait reçu une ligne de texte. Lorsque la commande read est utilisée pour interagir avec un utilisateur, on utilise l’option -e. Vous pouvez utiliser la commande echo pour afficher le contenu de la variable après l’exécution de la commande read.

1
read -e ma_variable
Fig. 8 – Lire la valeur d'une variable dans l'entrée standard

Il est possible d’afficher une invite de commande (prompt) avec l’option -p pour indiquer à l’utilisateur·rice ce que l’on attend d’elle ou de lui.

1
read -e -p "Veuillez saisir votre nom d'utilisateur·rice : " ma_variable 
Fig. 9 – Lire la valeur d'une variable dans l'entrée standard, en affichant un prompt

L’option -n permet de spécifier le nombre de caractère que la commande attend. Par exemple pour demander à l’utilisateur de répondre par oui ou non, on peut lui demain de saisir o pour oui ou n pour non.

1
read -e -p "Voulez continuer ? [o/n] : " -n 1 ma_variable
Fig. 10 – Lire un seul caractère de l'entrée standard

Enfin, on peut définir la valeur d’une variable avec une valeur qui provient de la sortie standard d’une autre commande (ou de manière générale, d’un autre programme). Par exemple, la commande pwd permet d’écrire le nom du répertoire de travail dans la sortie standard. En utilisant la substitution de commande $(...), on peut affecter la sortie de cette commande à une variable.

1
ma_variable=$(pwd)
Fig. 11 – Affecter le résultat d'une commande à une variable

Variable d’environnement

Une variable d’environnement est une variable stockée dans l’environnement d’un processus et dont la valeur est copiée lors de la création d’un processus enfant. Cela permet de partager des informations entre un processus parent et un processus enfant, au démarrage d’un processus enfant.

N’importe que variable peut devenir une variable d’environnement à l’aide de la commnde export. Par exemple :

1
export ma_variable
Fig. 12 – Exporter une variable pour en faire une variable d'environnement

Toutefois, par convention, le nom d’une variable d’environnement est écrit en UPPER_SNAKE_CASE. En outre, il est possible d’exporter et de définir une variable en une seule opération. Par exemple :

1
export DB_PASSWORD="mon mot de passe"
Fig. 13 – Exporter et définir une variable d'environnement

Une variable d’environnement s’utilise de la même manière qu’une variable normale. La seule différence est qu’elle est également disponible dans les processus enfant. Par exemple, créez un fichier script1.sh avec le contenu ci-dessous et accordez-vous la permission de l’exécuter (chmod +x ./script1.sh)

1
2
3
#! /bin/bash

echo $DB_PASSWORD
Fig. 14 – Afficher une variable d'environnement dans un processus enfant

Puis lancez votre script avec la commande ci-après. La commande echo devrait afficher la valeur que vous avez définit pour la variable d’environnement DB_PASSWORD.

1
./script1.sh
Fig. 12 – Exporter une variable pour en faire une variable d'environnement

Tâches

Bash

Vous devez commencer par vous familiariser avec le bash et en particulier avec les commandes suivantes : cd, ls, pwd, touch, cat, less, head, tail, mkdir, rm, cp, mv, find, chmod, chown, sudo. Assurez-vous de savoir utiliser ces commandes avant de poursuivre.

Attention : la commande rm supprime les fichiers de manière définitive, il n’est pas possible de récupérer ce que vous avez effacé. Assurez-vous d’avoir un backup (une copie) de votre répertoire de projet de votre machine physique avant de commencer.

Automatiser la création

Pour éviter d’avoir à taper sans cesse les mêmes commandes dans la fenêtre du terminal, on vous charge d’automatiser la procédure de création de la base de données. Pour cela vous devez réaliser un script bash qui effectuer les actions suivantes :

  1. Demander le mot de passe à l’utilisateur (attention à l’écho des caractères à l’écran).
  2. Supprimer la base de données existante.
  3. Créer la base de données avec le script SQL de création.
  4. Insérer les données de test avec le script SQL d’insertion des données de test (cela ne doit pas être le même que celui qui permet de créer la base de données !).

Demande de confirmation

Modifier votre script pour y ajouter la fonctionnalité suivante : si la base de données existe déjà, le script doit demander une confirmation à l’utilisateur avant de supprimer et de recréer la base de données.

Utilisation de variables d’environnement

Afin de permettre l’utilisation de votre script sans interaction avec l’utilisateur, modifier votre script pour utiliser le mot de passe et la confirmation qui se trouve dans les variables d’environnement CREATE_DB_PASSWORD et CREATE_DB_CONFIRMATION. Si les variables n’existent pas, le script doit demander les informations à l’utilisateur.