Script Bash modulaire > Module : Traces

Tout ce qui concerne la programmation.
Répondre
Avatar de l’utilisateur
dezix
Membre hyper actif
Membre hyper actif
Messages : 3546
Inscription : 04 juin 2016, 14:50
Status : Hors-ligne

Bonjour, :006:


Pour mes besoins personnels, j'écris quelques petits scripts de temps à autres.

Pour essayer de gagner un peu de temps et éviter de réinventer la roue à chaque fois,
je tente d'adopter (pas simple) une approche modulaire :

Code : Tout sélectionner

/my-script/
/my-script/main.sh
/my-script/modules/
/my-script/modules/module-1.sh
/my-script/modules/module-2.sh
/my-script/modules/main.conf
/my-script/modules/start.msge
/my-script/modules/...

Donc le début de my-script.sh peut ressembler à :

Code : Tout sélectionner

#!/bin/bash
#
####	VARIABLES	####################
#
# SCRIPT_DIR = Chemin du répertoire contenant le script
export SCRIPT_DIR=$(dirname "$(realpath "$0")") ;
#
# MOD_DIR = Chemin du répertoire des modules
export MOD_DIR="${SCRIPT_DIR}"/modules ;
#
#
### Traitement du fichier main.conf ###
#
source "${MOD_DIR}"/main.conf ;
#
#
#####	FONCTIONS	####################
#
#
#### MODULE-1
#
source "${MOD_DIR}"/module-1.sh ;
export -f MODULE-1 ;
#
...
#
#####	SCRIPT	#######################
#
#
# Message d'ouverture
cat "${MOD_DIR}"/start.msge ;
....


Voilà pour le décor.


Maintenant je voudrais ajouter un module : /my-script/modules/trace.sh
qui enverrait systématiquement :
  • toutes les sorties d'erreurs
  • de toutes les commandes exécutées par main.sh
dans : /my-script/logs/main.log

Du coup, je pourrais avoir pour chaque exécution du script :
un séparateur horodaté suivi des éventuelles erreurs envoyées...


J'espère que ça amuse les balèzes en script,
mais je ne vois pas comment pourrait fonctionner ce module (si c'est possible).


Merci pour vos conseils.
**Simple Utilisateur** -- Debian stable - XFCE
Avatar de l’utilisateur
dezix
Membre hyper actif
Membre hyper actif
Messages : 3546
Inscription : 04 juin 2016, 14:50
Status : Hors-ligne

Je me rends compte maintenant (j'avais le nez dans le guidon),
que ce que je souhaite pourrait se faire quasi naturellement de l'extérieur du script.

Pour le peu que je viens de tester :

Code : Tout sélectionner

$ ./main.sh 2>> ./log/main.log
à l'air de fonctionner sans plus de formalités.


Il va falloir que je teste d'avantage,
notamment ce qui arrive lorsqu'une erreur provient d'un sous-script.

Je reste à l'écoute....
**Simple Utilisateur** -- Debian stable - XFCE
Avatar de l’utilisateur
dezix
Membre hyper actif
Membre hyper actif
Messages : 3546
Inscription : 04 juin 2016, 14:50
Status : Hors-ligne

Voici où j'en suis...
un exemple valant mieux que de longues explications :

Structure

Code : Tout sélectionner

$ tree ./script-log/
./script-log/
├── log
├── modules
│   ├── error.sh
│   └── main.sh
└── script-log.sh

2 directories, 4 files


Script d'appel
Son rôle (ici) est de lancer le script principal en renvoyant stderr vers le fichier log
Il pourra aussi contenir au final l'appel d'un module nettoyeur ; p.ex. pour supprimer les fichiers temporaires...

Code : Tout sélectionner

$ cat ./script-log/script-log.sh

#!/bin/bash
#
# script-log.sh
#
# Script d'appel pour logs  > appel  main.sh  qui est le script principal réel.
#
#
####	VARIABLES	#####################################
#
# SCRIPT_DIR = Chemin du répertoire contenant le script
export SCRIPT_DIR=$(dirname "$(realpath "$0")") ;
#
# MOD_DIR = Chemin du répertoire des modules
export MOD_DIR="${SCRIPT_DIR}"/modules ;
##
# MAIN_LOG = Chemin du fichier de traces
export MAIN_LOG="${SCRIPT_DIR}"/log ;
#
#
####    SCRIPT    #######################################
#
# Traces
# Ajout d'un séparateur horodaté
echo -e "\n\n---- $(date -d now +%Y%m%d-%H%M%S) -------\n">> "${MAIN_LOG}" ;

# Appel du script principal
source "${MOD_DIR}"/main.sh 2>> "${MAIN_LOG}" ;
echo Fin de script-log ;
exit

Script principal (fait le job)

Code : Tout sélectionner

$ cat ./script-log/modules/main.sh

#!/bin/bash
#
# main.sh
#
# Script d'appel de error.sh pour test d'enregistrement des traces.
#
# ################################

source "${MOD_DIR}"/error.sh 2>> "${MAIN_LOG}" ;
echo Fin de main.sh ;
return


Module (fonction récurrente) réutilisable dans d'autres scripts
Ici contient quelques commandes génériques dont 2 rm produisant des erreurs

Code : Tout sélectionner

$ cat ./script-log/modules/error.sh

#!/bin/bash
#
# Script de test produisant volontairement des erreurs (2)
# Supprimer des fichiers inexistants pour générer ces erreurs

# ERREUR
rm spectre ;

touch nozerror.txt ;
echo Pas d\'erreur \! >> nozerror.txt ;

# ERREUR
rm zombi ;

echo Fin de error.sh ;
return

Exécution du script

Code : Tout sélectionner

$ ./script-log/script-log.sh
Fin de error.sh
Fin de main.sh
Fin de script-log


Fichier de traces après 2 exécutions

Code : Tout sélectionner

$ cat ./script-log/log

---- 20231009-123043 -------

/home/data/docs/tests/bash/script-log/modules/error.sh: ligne 1: !/bin/bash: Aucun fichier ou dossier de ce type
rm: impossible de supprimer 'spectre': Aucun fichier ou dossier de ce type
rm: impossible de supprimer 'zombi': est un dossier


---- 20231009-123214 -------

rm: impossible de supprimer 'spectre': Aucun fichier ou dossier de ce type
rm: impossible de supprimer 'zombi': est un dossier


Si vous voyez mieux, je suis preneur.
**Simple Utilisateur** -- Debian stable - XFCE
Avatar de l’utilisateur
dezix
Membre hyper actif
Membre hyper actif
Messages : 3546
Inscription : 04 juin 2016, 14:50
Status : Hors-ligne

Dans le fichier main.sh :

il n'est pas nécessaire, lors de l'appel d'un module ( avec source au moins)
de préciser la redirection des erreurs avec : 2>> "${MAIN_LOG}" ;

Du coup ça devient plus léger et surtout ça supprime les risques d'oublis.

Il faudra que je teste cela en utilisation réelle avec des scripts plus complexes,
mais pour maintenant (et mon usage personnel) je valide ce système :
  • Pas de nécessité d'un module effectuant la collecte des traces,
  • juste besoin d'une couche d'imbrication supplémentaire.
**Simple Utilisateur** -- Debian stable - XFCE
Répondre