config

Script

Ce billet présente différentes méthodes pour utiliser dans un script un fichier de configuration afin de lire et sauvegarder des données qui sont manipulées par le script.

Quand on écrit plusieurs scripts Unix, il arrive souvent que l'on est besoin de retrouver des valeurs de variables qui ont été modifiés par un autre script. On peut aussi avoir besoin de valeurs par défaut ou des constantes. On peut aussi décider que le script soit multilingue, par exemple Français et Anglais, et dans ce cas, il faut non seulement pouvoir sauvegarder le choix de la langue qui été fait par l'utilisateur pour pouvoir le retrouver si l'on relance le script à un autre moment. Mais il faut aussi pouvoir afficher tous les textes dans la langue qui a été choisie. Pour tous ces besoins, la solution est d'utiliser un fichier de configuration.

Présentation du problème à résoudre.

J'explique dans un autre blog comment utiliser la commande Whiptail dans un script pour que l'utilisateur puisse facilement interagir avec le script.

Rédigeons un script main.sh qui permette de choisir entre deux options en utilisant cette commande. Commençons par créer ce script en l'éditant avec la commande nano ...

nano main.sh

Nous allons tout d'abord utiliser la commande whiptail afin de poser la question avec les choix possibles ...

#!/bin/bash

myChoice=$(whiptail --menu "Choisissez votre langue" 12 60 2 \
 "FR" "Français" \
 "EN" "English" 3>&1 1>&2 2>&3)
echo $myChoice

Une fois le script écrit, on le rend exécutable avec la commande ...

chmod +x main.sh

Puis on l'exécute avec la commande ...

./main.sh

Le menu avec la question et les choix proposés s'affiche.

config_demo01

Une fois la sélection faite, le script renvoie la valeur sélectionnée "EN" ou "FR".

Rajoutons à notre script une variable qui permettent de conserver la valeur choisie ...

#!/bin/bash

myLanguage="FR"
myChoice=$(whiptail --menu "Choisissez votre langue" 12 60 2 \
 "FR" "Français" \
 "EN" "English" 3>&1 1>&2 2>&3)
echo "myLanguage :" $myLanguage
echo "myChoice   :" $myChoice
myLanguage=$myChoice

La variable myLanguage contiendra la valeur choisie et pourra être utilisée durant toute l'exécution du script tant qu'elle ne sera pas modifiée par le script. Mais à chaque fois que l'on relancera le script, elle reprendra toujours la valeur initiale "FR" qui est définie au début du script.

Pour régler ce problème nous allons définir la variable myLanguage dans un autre fichier puis inclure ce fichier dans notre script et ajouter une commande qui permette d'enregistrer la valeur choisie dans le fichier.

Création d'un fichier de configuration.

J'ai décrit dans un autre blog, include, comment intégrer dans un script du code qui provient d'un autre fichier de script. Nous allons réutiliser cette méthode pour stocker dans un autre fichier config.txt la variable myLanguage.

myLanguage="FR"

On inclut ensuite ce fichier dans le script principal.

#!/bin/bash

source config.txt
myChoice=$(whiptail --menu "Choisissez votre langue" 12 60 2 \
 "FR" "Français" \
 "EN" "English" 3>&1 1>&2 2>&3)
echo "myLanguage :" $myLanguage
echo "myChoice   :" $myChoice
myLanguage=$myChoice

Le script principal lors de son exécution va charger le fichier config.txt et interpréter son contenu comme si c'était lui aussi un script Unix. Il va donc initialiser la variable myLanguage avec la valeur "FR".

Il faut maintenant trouver une méthode qui permette de modifier dans le fichier config.txt la valeur de la variable myLanguage qui a été remplacée par "EN" ou "FR en fonction du choix de l'utilisateur.

Modification d'un paramètre du fichier de configuration.

Linux dispose d'une commande très puissante qui permet entre autres et à la fois de faire dans un fichier, une recherche de données, d'en modifier le contenu et de sauvegarder la modification. Il s'agit de la commande sed.

En écrivant la commande...

sed -i "s/^myLanguage=.*/myLanguage=$myLanguage/" "config.txt"

... Le paramètre -i indique que la commande va modifier le fichier auquel on accède.

L'action que la commande sed va exécuter se trouve dans la chaîne de caractères qui est encadrée par des ".

Le caractère s au début de cette chaîne indique que l'on effectue une action de recherche et de remplacement de chaîne. La chaîne de caractères qui suit le caractère / indique la valeur recherchée. Cette valeur recherchée se termine par un deuxième caractère /. La valeur recherchée est écrite en utilisant la grammaire des expressions régulières. En plaçant le caractère ^au début de la valeur de recherche, on indique que la valeur recherchée doit être au début de la chaîne de caractères. En plaçant les caractères .* à la fin de la valeur recherchée, on indique que la chaîne recherchée peut se terminer par n'importe quoi. Donc en écrivant ^myLanguage=.* on indique que l'on recherche une chaîne de caractères commençant par myLanguage= suivi de n'importe quelle chaîne de caractères. Donc si la chaîne de caractères contient myLanguage=FR ou myLanguage=EN, le résultat de la recherche sera positif.

La deuxième partie de l'action indique par quoi on remplace la chaîne recherchée. On peut placer des variables de scripts dans cette chaîne de remplacement. Si l’on écrit myLanguage=$myLanguage on remplace la valeur recherchée par la constante myLanguage= suivi du contenu de la variable de script $myLanguage.

Dans notre script cette variable de script pourra prendre les valeurs EN ou FR en fonction du choix que l'on aura fait avec le menu Whiptail. On aura donc en fonction de ce choix le résultat myLanguage=FR ou myLanguage=EN.

La commande sed se termine par le nom du fichier qui doit être lu et modifié. Dans cet exemple il s'agit du fichier config.txt qui est le fichier qui contient le paramètre de sélection du langage.

Et voilà, le tour est joué !

Avec le script ...

#!/bin/bash

source config.txt
myChoice=$(whiptail --menu "Choisissez votre langue" 12 60 2 \
 "FR" "Français" \
 "EN" "English" 3>&1 1>&2 2>&3)
echo "myLanguage :" $myLanguage
echo "myChoice   :" $myChoice
myLanguage=$myChoice
sed -i "s/^myLanguage=.*/myLanguage=$myLanguage/" "config.txt"

... On dispose maintenant d'un fichier de configuration de script modifiable.

Autre méthode avec l'outil Git.

La méthode présentée précédemment marche parfaitement. Mais dans le cas où l'on a un grand nombre de variables (on parle aussi de paramètres), elle manque de lisibilité. Toutes les variables se suivent les unes après les autres. Cependant, du fait que le fichier est interprété comme un fichier de script Unix, on peut ajouter des lignes de commentaires qui commence par # et insérer des lignes vides. Cela permet d'aérer le fichier de configuration et de le rendre plus compréhensible.

Mais imaginons que nous souhaitons utiliser un paramètre qui prenne une certaine valeur dans un cas et une autre valeur dans un autre cas. Avec cette première méthode on est obligé de donner un nom différent à ce paramètre pour chacune de ces valeurs. Cela rend le script qui utilise le fichier de configuration plus compliqué à écrire car il faut ajouter un test pour savoir à chaque fois si l'on est dans un cas ou un autre afin d'identifier le bon nom de variable.

Pour contourner cette difficulté, il existe un outil qui permet de créer des fichiers de configuration qui contiennent des groupes de paramètres. Il s'agit de Git. Cependant, Git est beaucoup plus qu'un outil de gestion de fichier de configuration.

Git est d'abord un outil de gestion des codes sources d'un projet informatique. C'est un système de contrôle de version de fichier conçu pour tout gérer, des petits aux très grands projets.

L'usage avec Git de cette fonction de gestion d'un fichier de configuration en dehors de la gestion d'un projet informatique est d'ailleurs assez peu connue. Elle est pourtant très pratique.

La définition d'un groupe de paramètres se fait en mettant dans le fichier de configuration le nom du groupe entre []. Le nom du groupe est libre mais il est préférable qu'il ne soit constitué que de caractères alphanumériques sans 'espace' ni caractères spéciaux. Mais on peut quand même mettre des '_' pour plus de lisibilité, par exemple '[GROUP_01]'.

Les paramètres du groupe sont définis ensuite dans les lignes qui suivent le nom du groupe mais cette fois-ci sans les '[]'. Je vous recommande également pour plus de lisibilité de décaler légèrement les paramètres sur la droite en plaçant 3 ou 4 espaces devant. Il n'est pas non plus nécessaire de coller les espaces et les valeurs comme on doit le faire avec la méthode précédente. Cela donne aussi plus de lisibilité. On peut enfin donner plusieurs fois le même nom pour un paramètre du moment qu'il est rattaché à chaque fois à un groupe différent.

On peut donc avoir un fichier de configuration config.cfg avec, par exemple, le contenu suivant ...

[GROUP_01]
    Param_01 = Valeur1
    Param_02 = Valeur2

[GROUP_02]
    Param_01 = Valeur1
    Param_02 = Valeur2

La lecture du paramètre se fait avec la commande git config en indiquant le fichier où se trouve le paramètre avec l'option --file ou -f. On précise ensuite le groupe auquel appartient ce paramètre et le nom du paramètre en les séparant par un .

Par exemple, pour placer le PARAM_01 du groupe GROUP_02 dans la variable de script myVariable, la commande Unix sera ...

myVariable=$(git config -f "config.cfg" GROUP_02.Param_01)

Il est bien sur tout à fait possible de définir le nom du groupe dans une variable ce qui peremttra d'avoir la même commande pour lire un paramètre mais pour un groupe différent.

myGroup="GROUP_02"
myVariable=$(git config -f "config.cfg" ${myGroup}.Param_01 $myVariable)

Pour remplacer la valeur de ce même paramètre, il suffit de rajouter à la fin de la même commande la nouvelle valeur.

Par exemple, pour remplacer la valeur de PARAM_01 du groupe GROUP_02 par la valeur de la variable de script myVariable, la commande Unix sera ...

git config -f "config.cfg" GROUP_02.Param_01 $myVariable

Et voilà !

Pour information : Les scripts d'installation des logiciels nécessaires au bon fonctionnement de la borne d'arcade que je présente dans cette autre page [rpi4mame] (/rpi4mame?target=_blank) et que vous pouvez télécharger ici utilisent ces deux méthodes et ont été gérés avec Git.

En remarque : Bien que cette méthode soit très pratique, elle nécessite que l'outil Git soit tout d'abord installé dans le système. La première méthode présentée dans ce billet ne nécessite aucune installation préalable.

Next Post