Recherche de site Web

Comment tracer l'exécution des commandes dans un script Shell avec Shell Tracing


Dans cet article de la série de débogage de scripts shell, nous expliquerons le troisième mode de débogage de scripts shell, à savoir le traçage du shell, et examinerons quelques exemples pour 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 vérification de syntaxe avec des exemples faciles à comprendre sur la façon d'activer le shell. débogage de script dans ces modes.

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

Le traçage Shell signifie simplement tracer l’exécution des commandes dans un script shell. Pour activer le traçage du shell, utilisez l'option de débogage -x.

Cela demande au shell 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 la disponibilité du système. Cependant, il contient des erreurs de syntaxe que nous devons rechercher 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

À partir de la sortie ci-dessus, nous pouvons observer qu'une commande est d'abord exécutée avant que sa sortie ne soit remplacée par la valeur d'une variable.

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

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

sudo bash -n sys_info.sh 

Si nous examinons le script shell d'un œil critique, nous réaliserons qu'il manque un mot fi de fermeture à l'if. Par conséquent, ajoutons-le et le nouveau script devrait maintenant ressembler à 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

Enregistrez à nouveau le fichier, appelez-le en tant que root et effectuez une vérification de 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 autre bug dans notre script à la ligne 21. Il nous reste donc encore quelques corrections de syntaxe à faire.

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

Nous allons ajouter le guillemet 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

Vérifiez maintenant syntaxiquement le script une fois de plus.

sudo bash -n sys_info.sh

La commande ci-dessus ne produira aucune sortie car notre script est désormais syntaxiquement correct. On peut également retracer l'exécution du script une seconde fois et cela 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 du script 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 ne peut ê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'instruction if expression [ "$UID" -ne "$ROOT_ID" ], une fois que nous n'utilisons pas l'opérateur numérique approprié ( -ne dans ce cas, ce qui signifie pas égal ), on se retrouve avec une possible erreur logique.

En supposant que nous utilisions -eq (signifie égal à), cela permettrait à n'importe quel utilisateur 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 retraç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 invoquez le script, nous pouvons voir qu'un utilisateur système normal peut exécuter le script sans sudo comme dans le résultat 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 des scripts shell, le formulaire de réponse ci-dessous peut être utilisé pour nous adresser des questions ou des commentaires concernant ce guide ou l'ensemble de la série en 3 parties.