Recherche de site Web

Comment suivre l’exécution de commandes dans un script shell avec le traçage shell


Dans cet article de la série de débogage de script shell, nous allons expliquer le troisième mode de débogage de script shell, c’est-à-dire le traçage de shell, et regarder quelques exemples pour démontrer comment il fonctionne et comment il peut être utilisé.

La partie précédente de cette série met clairement en lumière les deux autres modes de débogage des scripts shell : le mode verbeux et le mode de vérification de la syntaxe, avec des exemples faciles à comprendre de la façon d’activer le débogage des scripts shell dans ces modes.

  1. Comment activer le mode de débogage de script Shell sous Linux - Partie 1
  2. Comment effectuer une vérification de syntaxe en mode de débogage dans les scripts shell - Partie 2

Le traçage de l’interpréteur de commandes consiste simplement à suivre l’exécution des commandes dans un script shell. Pour activer le suivi de l’interpréteur de commandes, utilisez l’option de débogage -x.

Cela indique à l’interpréteur de commandes d’afficher toutes les commandes et leurs arguments sur le terminal au fur et à mesure de leur exécution.

Nous utiliserons le script shell sys_info.sh ci-dessous, qui imprime brièvement la date et l’heure de votre système, le nombre d’utilisateurs connectés et le temps de fonctionnement du système. Cependant, il contient des erreurs de syntaxe que nous devons trouver et corriger.

#!/bin/bash
#script to print brief system info

ROOT_ID="0"

DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`

check_root(){
    if [ "$UID" -ne "$ROOT_ID" ]; then
        echo "You are not allowed to execute this program!"
        exit 1;    
}

print_sys_info(){
    echo "System Time    : $DATE"
    echo "Number of users: $NO_USERS"
    echo "System Uptime  : $UPTIME
}

check_root
print_sys_info

exit 0

Enregistrez le fichier et rendez le script exécutable. Le script ne peut être exécuté que par root, utilisez donc la commande sudo pour l’exécuter comme ci-dessous :

$ chmod +x sys_info.sh
sudo bash -x sys_info.sh

D’après la sortie ci-dessus, nous pouvons observer qu’une commande est d’abord exécutée avant que sa sortie ne soit substituée en tant que valeur d’une variable.

Par exemple, la date a été exécutée pour la première fois et sa sortie a été substituée en tant que valeur de la variable DATE.

Nous pouvons effectuer une vérification de syntaxe pour n’afficher que les erreurs de syntaxe comme suit :

$ sudo bash -n sys_info.sh 

Si nous regardons le script shell d’un œil critique, nous nous rendons compte qu’il manque un mot fi de fermeture à l’instruction if. Par conséquent, ajoutons-le et le nouveau script devrait maintenant ressembler à ce qui suit :

#!/bin/bash
#script to print brief system info

ROOT_ID="0"

DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`

check_root(){
    if [ "$UID" -ne "$ROOT_ID" ]; then
        echo "You are not allowed to execute this program!"
        exit 1;
   fi    
}

print_sys_info(){
    echo "System Time    : $DATE"
    echo "Number of users: $NO_USERS"
    echo "System Uptime  : $UPTIME
}

check_root
print_sys_info

exit 0

Enregistrez à nouveau le fichier et appelez-le en tant que root et vérifiez la syntaxe :

$ sudo bash -n sys_info.sh

Le résultat de notre opération de vérification de syntaxe ci-dessus montre toujours qu’il y a un bogue supplémentaire dans notre script à la ligne 21. Nous avons donc encore quelques corrections de syntaxe à faire.

Si nous parcourons le script de manière analytique une fois de plus, l’erreur de la ligne 21 est due à un guillemet double fermant manquant ( ") dans la dernière commande echo à l’intérieur de la fonction print_sys_info.

Nous allons ajouter le guillemet double fermant dans la commande echo et enregistrer le fichier. Le script modifié est ci-dessous :

#!/bin/bash
#script to print brief system info

ROOT_ID="0"

DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`

check_root(){
    if [ "$UID" -ne "$ROOT_ID" ]; then
        echo "You are not allowed to execute this program!"
        exit 1;
    fi
}

print_sys_info(){
    echo "System Time    : $DATE"
    echo "Number of users: $NO_USERS"
    echo "System Uptime  : $UPTIME"
}

check_root
print_sys_info

exit 0

Maintenant, vérifiez une fois de plus le script syntaxiquement.

$ sudo bash -n sys_info.sh

La commande ci-dessus ne produira aucun résultat car notre script est maintenant syntaxiquement correct. On peut aussi bien retracer l’exécution du script une seconde fois et ça devrait bien fonctionner :

$ sudo bash -x sys_info.sh

Exécutez maintenant le script.

$ sudo ./sys_info.sh

Importance du suivi de l’exécution des scripts shell

Le traçage des scripts shell nous aide à identifier les erreurs de syntaxe et, plus important encore, les erreurs logiques. Prenez par exemple la fonction check_root dans le script shell sys_info.sh, qui est destinée à déterminer si un utilisateur est root ou non, puisque le script n’est autorisé à être exécuté que par le superutilisateur.

check_root(){
    if [ "$UID" -ne "$ROOT_ID" ]; then
        echo "You are not allowed to execute this program!"
        exit 1;
    fi
}

La magie ici est contrôlée par l’expression de l’instruction if [ « $UID » -ne « $ROOT_ID » ], une fois que nous n’utilisons pas l’opérateur numérique approprié (-ne dans ce cas, ce qui signifie non égal à ), nous nous retrouvons avec une erreur logique possible.

En supposant que nous utilisions -eq ( signifie égal à), cela permettrait à tout utilisateur du système ainsi qu’à l’utilisateur root d’exécuter le script, d’où une erreur logique.

check_root(){
    if [ "$UID" -eq "$ROOT_ID" ]; then
        echo "You are not allowed to execute this program!"
        exit 1;
    fi
}

Remarque : Comme nous l’avons vu précédemment au début de cette série, la commande intégrée set shell peut activer le débogage dans une section particulière d’un script shell.

Par conséquent, la ligne ci-dessous nous aidera à trouver cette erreur logique dans la fonction en traçant son exécution :

Le script avec une erreur logique :

#!/bin/bash
#script to print brief system info

ROOT_ID="0"

DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`

check_root(){
    if [ "$UID" -eq "$ROOT_ID" ]; then
        echo "You are not allowed to execute this program!"
        exit 1;
    fi
}

print_sys_info(){
    echo "System Time    : $DATE"
    echo "Number of users: $NO_USERS"
    echo "System Uptime  : $UPTIME"
}

#turning on and off debugging of check_root function
set -x ; check_root;  set +x ;
print_sys_info

exit 0

Enregistrez le fichier et appelez le script, nous pouvons voir qu’un utilisateur système normal peut exécuter le script sans sudo comme dans la sortie ci-dessous. En effet, la valeur de USER_ID est 100, ce qui n’est pas égal à la racine ROOT_ID qui est 0.

$ ./sys_info.sh

Eh bien, c’est tout pour l’instant, nous sommes arrivés à la fin de la série de débogage de script shell, le formulaire de réponse ci-dessous peut être utilisé pour nous adresser toutes questions ou commentaires, concernant ce guide ou toute la série en 3 parties.

Articles connexes: