diff --git a/content/articles/2022/bash_gerer_les_messages_avance/files/scripts.tar.gz b/content/articles/2022/bash_gerer_les_messages_avance/files/scripts.tar.gz deleted file mode 100644 index b680855..0000000 Binary files a/content/articles/2022/bash_gerer_les_messages_avance/files/scripts.tar.gz and /dev/null differ diff --git a/content/articles/2022/bash_gerer_les_messages_avance/index.md b/content/articles/2022/bash_gerer_les_messages_avance/index.md deleted file mode 100644 index 1c7c39b..0000000 --- a/content/articles/2022/bash_gerer_les_messages_avance/index.md +++ /dev/null @@ -1,398 +0,0 @@ -Title: Bash avancé: Gérer les messages -Category: sysadmin -Tags: bash, script, pl-fr -Date: 2022-01-30 1:30 -Cover: assets/backgrounds/article_bash_messages.jpg - -Dans ce premier article de l'année 2022, nous allons voir comment gérer les -messages de sorties de nos scripts Bash. L'idée ici est de proposer trois type -de messages dans un fichiers que nous pourrons ensuite inclure dans nos scripts -à l'aide de la commande `source`. - -Ces messages seront de 3 types différents: - - * **messages standards** envoyés sur la sortie standard - * **messages de débogage** affichés si une variable `DEBUG` est positionnée et - envoyés vers la sortie d'erreur - * **message d'erreur** envoyés sur la sortie d'erreur. - -Nous utiliserons quelques spécificité de bash nous permettant d'agrémenter nos -sorties. - -## Une première version - -Cette première ébauche de cette librairie contient 3 fonctions répondant à la -demande formulée en introduction. Appelons ce fichier `messages.sh`. - -```bash -#!/bin/env bash - -msg() { - local message="$*" - - # Si la fonction est appelée sans paramètres, on la quitte - [ -z "$message" ] && return - printf "%b\n" "$message" -} - -debug() { - local message="$*" - # si la variable $DEBUG n'est pas définie ou si sa valeur - # est différente de 1, on quite notre fonction. - [ -z "$DEBUG" || $DEBUG -ne 1 ] && return - [ -z "$message" ] && return - >&2 msg "DEBUG: $message" -} - -error() { - local message="$*" - [ -z "$message" ] && return - >&2 msg "ERROR: $message" } -``` - -Vous remarquez que les fonctions `error` et `debug` utilisent la fonction -`message` mais son appel est précédé de `>&2` afin que la sortie se fasse sur -`SRDERR`. - -Le `printf` de notre fonction `msg` utilise `%b` pour afficher le contenu de la -`message`. Ainsi les séquences échappées par un antislash seront interprétées. -Nous aborderons le sujets dans la partie suivante. - -Pour les tester, créons un script `test.sh` dans le même répertoire -que notre librairie avec le code suivant: - -```bash -#!/usr/bin/env bash - -# inclusion de notre librairie de message, il ne faut pas oublier -# d'afficher une erreur et teminer notre script si il y a un problème -# lors de son chargement. - -source message.sh || { >&2 printf "Can't load message.sh"; exit 1; } - -debug "We will display a message" -msg "Test Message" -debug "We will display an error" -error "This is an error" - -exit 0 -``` - -Pour tester il suffit de lancer la commande : - -```shell -./test.sh -Test Message -ERROR: This is an error -``` - -Comme il n'y a pas de variable `$DEBUG` de définie, les message de débogage ne -sont pas affichés, pour tester ces messages il suffit de faire: - -```none -$ DEBUG=1 ./test.sh -DEBUG: We will display a message -Test Message -DEBUG: We will display an error -ERROR: This is an error -``` - -## Ajouter un peu de couleur - -Personnellement, **j'aime avoir un peu de couleur dans mon terminal**, les -choses apparaissent souvent plus claire. Pour nos messages, nous pouvons faire -de même. - -La commande `printf` permet d'insérer des code couleur (entre autres), utilisons -le rouge pour les messages d'erreur (logique non?) et le bleu pour les messages -de débogages - -```bash -debug() { - local message="$*" - [[ -z $DEBUG || $DEBUG -ne 1 ]] && return - [ -n "$message" ] && >&2 msg "\e[34mDEBUG: $message\e[0m" -} - -error() { - local message="$*" - [ -n message ] && >&2 msg "\e[31mERROR: $message\e[0m" -} -``` - -Ici la commande `\e[34m` permet de choisir la couleur bleue et `\e[0m` de -revenir à la normale. C'est ici que le choix de `%b` pour le formatage de la -variable `$message` est important: **`printf` interprètera nos commande -échappées avec l'antislash**. - -La couleur c'est bien, mais si on décide de rediriger une sortie (ou les deux) -de notre script dans un fichier voici son contenu ouvert dans `vim`: - -```none -DEBUG: We will display a message -Test Message -DEBUG: We will display an error -ERROR: This is an error -``` - -Nous allons justement régler ce problème dans le paragraphe suivant. - -## Sortie vers un fichier - -Il est souvent nécessaire de **rediriger les sorties** d'un de nos script vers -un fichier. Surtout lorsqu'il est exécuté en dehors d'une session interactive -- -dans une tâche *cron* par exemple. - -Dans ce cas il peut être intéressant d'ajouter un horodatage en début de ligne -comme dans la plupart des applications qui effectuent de la journalisation. Bash -dispose d'un opérateur de test permettant de savoir si la sortie demandée est un -terminal interactif ou non: `-t`. - -Le code prend un peu de poids : - - * On ajoute une condition dans chacune de nos trois fonction d'origine afin de - tester le type de sortie. - * On y ajoute une fonction `log` qui se charge de traiter notre sortie - lorsque elle est redirigée vers un fichier en ajoutant une information de - date / heure au début de la ligne. - * Le format de cette date est paramétrable à l'aide de la variable `$DATE_FMT`, - dans l'exemple un *timestamp*. - -Voici le nouveau code : - -```bash -#!/usr/bin/env bash - -DATE_FMT="+%s" - -msg() { - local message="$*" - [ -z "$message" ] && return - if [ -t 1 ] - then - printf "%b\n" "$message" - else - log "$message" - fi -} - -log() { - local message="$*" - [ -z "$message" ] && return - - # On veux conserver les sauts de ligne et les tabulation du - # message, utilisons alors %b ... - printf "%s %b\n" "$(date $DATE_FMT)" "$message" -} - -debug() { - local message="$*" - [[ -z $DEBUG || $DEBUG -ne 1 ]] && return - [ -z "$message" ] && return - message="DEBUG: $message" - if [ -t 2 ] - then - >&2 msg "\e[34m$message\e[0m" - else - >&2 log "$message" - fi -} - -error() { - local message="$*" - [ -z message ] && return - message="ERROR: $message" - if [ -t 2 ] - then - >&2 msg "\e[31m$message\e[0m" - else - >&2 log $message - fi -} -``` - -## Améliorer les informations de débogage - -Lors de la sortie d'information de débogage via notre fonction `debug`, il peut -être intéressant d'afficher des **informations supplémentaires** comme par -exemple la fonction en cours et le fichier source. Ces informations peuvent être -très précieuse surtout dans le cas d'un projet conséquent répartis sur plusieurs -fichiers sources. - -Ces informations sont disponible via des variables spéciales de bash : - - * `BASH_SOURCE`: un tableau reprenant **la pile des fichiers** scripts - utilisés. `$BASH_SOURCE[0]` représente le fichier source de la fonction - en cours. - * `FUNCNAME`: est un tableau reprenant la **liste des fonctions appelées**, en - quelque sorte notre pile d'appel. Cette variable est liée à la précédente, - `BASH_SOURCE[n]` représente la source de la fonction `FUNCNAME[n]` et - `FUNCNAME[0]` la fonction courante. - -Dans notre fonction `debug`, `FUNCNAME[0]` correspond donc à `debug`, pour -retrouver la fonction appelante, il faut chercher du côté de `FUNCNAME[1]` (et -donc de `BASH_SOURCE[1]`). - -Voici donc le nouveau code de notre fonction: - -```bash -debug() { - local message="$*" - [[ -z $DEBUG || $DEBUG -ne 1 ]] && return - [ -z "$message" ] && return - - # On affiche les informations supplémentaires pour le débogage - message="DEBUG [${BASH_SOURCE[1]}:${FUNCNAME[1]}]: $message" - if [ -t 2 ] - then - >&2 msg "\e[34m$message\e[0m" - else - >&2 log "$message" - fi -} -``` - -Afin de tester le fonctionnement de notre modification, nous allons inclure un -autre fichier bash dans notre script de test. Voici notre fichier `include.sh`: - -```bash -#!/usr/bin/env bash - -myfunct() { - local a=10 - debug "my a variable is $a" - msg "value of 'a' squared $(( a * a ))" -} -``` - -Et modifions notre fichier `test.sh` afin d'inclure notre fichier comme -ci-dessous : - -```bash -source message.sh || { >&2 printf "Can't load message.sh"; exit 1; } -source include.sh || { >&2 printf "Can't load include.sh"; exit 1; } - -# Appel de notre fonction venue de include.sh -myfunct - -debug "We will display a message" -msg "Test Message" -``` - -Et voici sa sortie: - -```none -$ DEBUG=1 ./test.sh -DEBUG [include.sh:myfunct]: my a variable is 10 -value of 'a' squared: 100 -DEBUG [./test.sh:main]: We will display a message -Test Message -``` - -Le fichier source et la fonction appelée sont bien affichés. Bash dispose -d'autre variables utiles que vous trouverez dans l'aide : `man bash`. - -## Améliorer les sorties d'erreur - -Avec ce que nous venons de voir, nous pouvons maintenant améliorer la sortie -d'erreur. Pourquoi nous n'afficherions pas, lorsque le mode de débogage est -activé, une sorte de *stack trace*? - -Pour ce faire, nous pouvons utiliser la variable `${#FUNCNAME[@]}` qui va nous -donner le nombre de fonctions appelées. Voici le code de notre nouvelle fonction -`error`: - -```bash -error() { - local message="$*" - [ -z "$message" ] && return - message="ERROR: $message" - - # Nous affichons notre "stack trace si le mode débogage est activé - if [[ -n $DEBUG && $DEBUG -eq 1 ]] - then - message="$message\n\tstack trace:\n" - - # Il nous suffit pour ça de parcourir notre tableau FUNCNAME et - # d'afficher le BASH_SOURCE et BASH_LINENO correspondant - for (( i=1; i<${#FUNCNAME[@]}; i++ )) - do - message="${message}\t source:${BASH_SOURCE[i]}" - message="${message} function:${FUNCNAME[$i]}" - - # Attention, il faut prendre ici la valeur de n-1 pour BASH_LINENO - message="${message} line:${BASH_LINENO[$i-1]}\n" - done - fi - if [ -t 2 ] - then - >&2 msg "\e[31m$message\e[0m" - else - >&2 log "$message" - fi -} -``` - -Pour tester notre nouvelle fonction, rajoutons le code suivant dans le fichier -`include.sh`: - -```bash - -check_file() { - if [ ! -f "monfichier.txt" ] - then - display_error "File monfichier.txt not found" - fi -} - -display_error() { - error "$*" -} -``` - -Et enfin modifions notre fichier `test.sh` comme ci-dessous: - -```bash -#!/usr/bin/env bash -source message.sh || { >&2 printf "Can't load message.sh"; exit 1; } -source include.sh || { >&2 printf "Can't load include.sh"; exit 1; } -myfunct -check_file -debug "We will display a message" -msg "Test Message" -error "This is a simple error message" -exit 0 -``` - -Lors de l'exécution de notre script de test avec le mode débogage, nous pouvons -voir que tous les éléments demandés sont présent: - -```none -$ DEBUG=1 ./test.sh -DEBUG [include.sh:myfunct]: my a variable is 10 -value of 100 -ERROR: File monfichier.txt not found - stack trace: - source:include.sh function:display_error line:18 - source:include.sh function:check_file line:13 - source:./test.sh function:main line:6 - -DEBUG [./test.sh:main]: We will display a message -Test Message -ERROR: This is a simple error message - stack trace: - source:./test.sh function:main line:9 - -``` - -## En conclusion - -Nous avons vu tout au long de cet article comment utiliser des fonctions pour -afficher vos messages, que se soit pour déboguer, afficher des erreurs ou de -simples messages. - -Pensez que vous pouvez placer votre "bibliothèque" dans un endroit pr esent dans -la variable d'environnement `$PATH` et ainsi l'inclure dans n'importe quel -script. - -Les fichiers d'exemple sont disponibles [ici]({attach}files/scripts.tar.gz). diff --git a/content/pages/cv.md b/content/pages/cv.md index 2b5984f..937fd07 100644 --- a/content/pages/cv.md +++ b/content/pages/cv.md @@ -3,8 +3,9 @@ slug: a-propos cover: assets/backgrounds/gnu.jpg Je suis Yorick, marié, papa de deux enfants, habitant Bordeaux et -**administrateur système spécialisé en technologies Open-source**.Je suis aussi -étudiant en Master Ingénieurie de l'Informatique à l'Université de Bordeaux. +**administrateur système spécialisé en technologies Open-source**. Je suis +actuellement administrateur système. Je suis aussi étudiant en licence +professionnelle ADSILLH. Si vous voulez en apprendre plus, [téléchargez mon CV][l_cv], ou son [code source][l_cv_code]. @@ -14,8 +15,8 @@ Si vous voulez en apprendre plus, [téléchargez mon CV][l_cv], ou son ### le collectif Giroll [Giroll][l_giroll], pour Gironde Logiciels Libres, et un collectif héthéroclite -réuni autour des cultures libres, je suis un **membre fondateur** et ancien -animateur de l'émission de radio mensuelle "Radio Giroll". +réuni autour des cultures libres, je suis un **membre fondateur** et animateur de +l'émission de radio mensuelle "Radio Giroll". ### Khal