Sådan spores udførelse af kommandoer i Shell Script med Shell Tracing


I denne artikel i fejlsøgningsserien om shell-script forklarer vi den tredje fejlretningstilstand for shell-script, det vil sige shell-sporing, og se på nogle eksempler for at demonstrere, hvordan det fungerer, og hvordan det kan bruges.

Den foregående del af denne serie kaster tydeligt lys over de to andre shell-script-fejlfindingsmetoder: detaljeret tilstand og syntaks-kontroltilstand med letforståelige eksempler på, hvordan man aktiverer fejlfinding af shell-script i disse tilstande.

  1. Sådan aktiveres shell script-fejlretningstilstand i Linux - del 1
  2. Sådan udføres syntaks-kontrol af fejlretningstilstand i shell-scripts - del 2

Shell-sporing betyder simpelthen at spore udførelsen af kommandoerne i et shell-script. For at aktivere shell-sporing skal du bruge fejlfindingsindstillingen -x .

Dette leder shell til at vise alle kommandoer og deres argumenter på terminalen, når de udføres.

Vi bruger sys_info.sh shell-scriptet nedenfor, der kort udskriver din systemdato og -tid, antallet af brugere, der er logget ind og systemets oppetid. Den indeholder dog syntaksfejl, som vi skal finde og rette.

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

Gem filen, og gør scriptet eksekverbart. Scriptet kan kun køres med rod, og brug derfor sudo-kommandoen til at køre det som nedenfor:

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

Fra ovenstående output kan vi se, at en kommando først udføres, før dens output erstattes af værdien af en variabel.

For eksempel blev datoen først udført, og dens output blev erstattet som værdien af variablen DATO.

Vi kan udføre syntakskontrol for kun at vise syntaksfejlene som følger:

$ sudo bash -n sys_info.sh 

Hvis vi ser kritisk på shell-scriptet, vil vi indse, at if-sætningen mangler et afsluttende fi -ord. Lad os derfor tilføje det, og det nye script skal nu se ud som nedenfor:

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

Gem filen igen, og påkald den som root, og udfør en syntakskontrol:

$ sudo bash -n sys_info.sh

Resultatet af vores syntaks-kontroloperation ovenfor viser stadig, at der er endnu en fejl i vores script på linje 21. Så vi har stadig nogle syntakskorrektioner at gøre.

Hvis vi kigger igennem scriptet analytisk en gang til, skyldes fejlen på linje 21 et manglende lukkende dobbelt citat (”) i den sidste ekkokommando inde i print_sys_info -funktionen .

Vi tilføjer det afsluttende dobbelt citat i ekkokommandoen og gemmer filen. Det ændrede script er nedenfor:

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

Kontroller nu syntaktisk scriptet en gang til.

$ sudo bash -n sys_info.sh

Kommandoen ovenfor producerer ikke nogen output, fordi vores script nu er syntaktisk korrekt. Vi kan lige så godt spore udførelsen af scriptet alt for anden gang, og det skal fungere godt:

$ sudo bash -x sys_info.sh

Kør nu scriptet.

$ sudo ./sys_info.sh

Betydningen af sporing af Shell Script-udførelse

Sporing af shell-script hjælper os med at identificere syntaksfejl og vigtigere, logiske fejl. Tag f.eks. check_root -funktionen i sys_info.sh shell-scriptet, som er beregnet til at afgøre, om en bruger er root eller ej, da scriptet kun må udføres af superbrugeren.

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

Magien her styres af if-sætningen udtryk ["$ UID" -ne "$ ROOT_ID"] , når vi ikke bruger den passende numeriske operator ( -ne i dette tilfælde, hvilket betyder ikke lige), ender vi med en mulig logisk fejl.

Forudsat at vi brugte -eq (betyder lig med), vil dette tillade enhver systembruger såvel som rootbrugeren at køre scriptet, derfor en logisk fejl.

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

Bemærk: Som vi kiggede på før i starten af denne serie, kan den indbyggede sæt shell-kommando aktivere fejlretning i et bestemt afsnit af et shell-script.

Derfor vil linjen nedenfor hjælpe os med at finde denne logiske fejl i funktionen ved at spore dens udførelse:

Scriptet med en logisk fejl:

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

Gem filen og påkald scriptet, vi kan se, at en almindelig systembruger kan køre scriptet uden sudo som i output nedenfor. Dette skyldes, at værdien af USER_ID er 100, hvilket ikke er lig med rod ROOT_ID, som er 0.

$ ./sys_info.sh

Nå, det er det for nu, vi er kommet til slutningen af shell-fejlfindingsserien, svarformularen nedenfor kan bruges til at stille spørgsmål eller feedback til os angående denne guide eller hele 3-delt serien.