Website-Suche

So verfolgen Sie die Ausführung von Befehlen in Shell-Skripten mit Shell-Tracing


In diesem Artikel der Shell-Skript-Debugging-Reihe erklären wir den dritten Shell-Skript-Debugging-Modus, das Shell-Tracing, und sehen uns einige Beispiele an, um zu demonstrieren, wie er funktioniert und wie er verwendet werden kann.

Der vorherige Teil dieser Serie beleuchtet deutlich die beiden anderen Shell-Skript-Debugging-Modi: Ausführlicher Modus und Syntaxprüfung-Modus mit leicht verständlichen Beispielen für die Aktivierung der Shell Skript-Debugging in diesen Modi.

  1. So aktivieren Sie den Shell-Skript-Debugging-Modus unter Linux – Teil 1
  2. So führen Sie den Debugging-Modus für die Syntaxprüfung in Shell-Skripten durch – Teil 2

Shell-Tracing bedeutet einfach, die Ausführung der Befehle in einem Shell-Skript zu verfolgen. Um die Shell-Ablaufverfolgung zu aktivieren, verwenden Sie die Debugging-Option -x.

Dadurch wird die Shell angewiesen, alle Befehle und ihre Argumente auf dem Terminal anzuzeigen, während sie ausgeführt werden.

Wir verwenden das folgende Shell-Skript sys_info.sh, das kurz das Datum und die Uhrzeit Ihres Systems, die Anzahl der angemeldeten Benutzer und die Systemverfügbarkeit ausgibt. Es enthält jedoch Syntaxfehler, die wir finden und korrigieren müssen.

#!/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

Speichern Sie die Datei und machen Sie das Skript ausführbar. Das Skript kann nur von Root ausgeführt werden. Verwenden Sie daher den Befehl sudo, um es wie folgt auszuführen:

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

Anhand der obigen Ausgabe können wir erkennen, dass ein Befehl zuerst ausgeführt wird, bevor seine Ausgabe als Wert einer Variablen ersetzt wird.

Beispielsweise wurde das Datum zuerst ausgeführt und seine Ausgabe wurde als Wert der Variablen DATE ersetzt.

Wir können eine Syntaxprüfung durchführen, um nur die Syntaxfehler wie folgt anzuzeigen:

sudo bash -n sys_info.sh 

Wenn wir das Shell-Skript kritisch betrachten, werden wir feststellen, dass der if-Anweisung ein abschließendes fi-Wort fehlt. Fügen wir es daher hinzu und das neue Skript sollte nun wie folgt aussehen:

#!/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

Speichern Sie die Datei erneut, rufen Sie sie als Root auf und führen Sie eine Syntaxprüfung durch:

sudo bash -n sys_info.sh

Das Ergebnis unserer obigen Syntaxprüfung zeigt immer noch, dass es in Zeile 21 einen weiteren Fehler in unserem Skript gibt. Wir müssen also noch einige Syntaxkorrekturen vornehmen.

Wenn wir das Skript noch einmal analytisch durchsehen, ist der Fehler in Zeile 21 auf ein fehlendes schließendes Anführungszeichen ( ”) im letzten Echo-Befehl innerhalb des print_sys_info-Funktion.

Wir werden das schließende doppelte Anführungszeichen in den Befehl echo einfügen und die Datei speichern. Das geänderte Skript ist unten:

#!/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

Überprüfen Sie nun das Skript noch einmal syntaktisch.

sudo bash -n sys_info.sh

Der obige Befehl erzeugt keine Ausgabe, da unser Skript jetzt syntaktisch korrekt ist. Wir können die Ausführung des Skripts auch ein zweites Mal verfolgen und es sollte gut funktionieren:

sudo bash -x sys_info.sh

Führen Sie nun das Skript aus.

sudo ./sys_info.sh

Bedeutung der Shell-Skriptausführungsverfolgung

Die Ablaufverfolgung von Shell-Skripten hilft uns, Syntaxfehler und, was noch wichtiger ist, logische Fehler zu identifizieren. Nehmen Sie zum Beispiel die Funktion check_root im Shell-Skript sys_info.sh, die feststellen soll, ob ein Benutzer Root ist oder nicht, da das Skript nur ausgeführt werden darf durch den Superuser.

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

Die Magie hier wird durch den if-Anweisung-Ausdruck [ "$UID" -ne "$ROOT_ID" ] gesteuert, sobald wir nicht den geeigneten numerischen Operator ( verwenden -ne in diesem Fall, was ungleich bedeutet), erhalten wir möglicherweise einen logischen Fehler.

Unter der Annahme, dass wir -eq (bedeutet gleich) verwenden, würde dies jedem Systembenutzer sowie dem Root-Benutzer erlauben, das Skript auszuführen, was einen logischen Fehler darstellt.

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

Hinweis: Wie wir bereits zu Beginn dieser Serie gesehen haben, kann der integrierte Befehl set Shell das Debuggen in einem bestimmten Abschnitt eines Shell-Skripts aktivieren.

Daher hilft uns die folgende Zeile, diesen logischen Fehler in der Funktion zu finden, indem sie ihre Ausführung verfolgt:

Das Skript mit einem logischen Fehler:

#!/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

Speichern Sie die Datei und rufen Sie das Skript auf. Wir können sehen, dass ein normaler Systembenutzer das Skript ohne sudo ausführen kann, wie in der Ausgabe unten. Dies liegt daran, dass der Wert von USER_ID 100 ist, was nicht mit der Root-ROOT_ID übereinstimmt, die 0 ist.

./sys_info.sh

Nun, das ist es für den Moment, wir sind am Ende der Shell-Skript-Debugging-Serie angelangt. Das Antwortformular unten kann verwendet werden, um Fragen oder Feedback zu diesem Handbuch oder der gesamten dreiteiligen Serie an uns zu richten.