Cum să urmăriți execuția comenzilor în scriptul Shell cu urmărirea Shell


În acest articol din seria de depanare a scriptului shell, vom explica al treilea mod de depanare a scriptului shell, adică urmărirea shell-ului și vom analiza câteva exemple pentru a demonstra cum funcționează și cum poate fi utilizat.

Partea anterioară a acestei serii aruncă în mod clar lumină asupra celorlalte două moduri de depanare a scriptului shell: modul verbose și modul verificare a sintaxei cu exemple ușor de înțeles despre cum să activați shell. depanarea scriptului în aceste moduri.

  1. Cum să activați modul de depanare Shell Script în Linux - Partea 1
  2. Cum se efectuează verificarea sintaxei în modul de depanare în scripturile Shell - Partea 2

Urmărirea shell înseamnă pur și simplu urmărirea execuției comenzilor într-un script shell. Pentru a activa urmărirea shell-ului, utilizați opțiunea de depanare -x.

Aceasta direcționează shell-ul să afișeze toate comenzile și argumentele lor pe terminal pe măsură ce sunt executate.

Vom folosi scriptul shell sys_info.sh de mai jos, care tipărește pe scurt data și ora sistemului, numărul de utilizatori conectați și timpul de funcționare al sistemului. Cu toate acestea, conține erori de sintaxă pe care trebuie să le găsim și să le corectăm.

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

Salvați fișierul și faceți scriptul executabil. Scriptul poate fi rulat numai de către root, prin urmare utilizați comanda sudo pentru a-l rula după cum urmează:

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

Din rezultatul de mai sus, putem observa că, o comandă este mai întâi executată înainte ca ieșirea sa să fie înlocuită ca valoare a unei variabile.

De exemplu, data a fost executată pentru prima dată și rezultatul său a fost înlocuit ca valoare a variabilei DATE.

Putem efectua verificarea de sintaxă pentru a afișa numai erorile de sintaxă după cum urmează:

sudo bash -n sys_info.sh 

Dacă ne uităm critic la scriptul shell, ne vom da seama că în instrucțiunea if lipsește un cuvânt de închidere fi. Prin urmare, haideți să-l adăugăm și noul script ar trebui să arate acum ca mai jos:

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

Salvați din nou fișierul și invocați-l ca rădăcină și verificați sintaxa:

sudo bash -n sys_info.sh

Rezultatul operațiunii noastre de verificare a sintaxei de mai sus arată că mai există o eroare în scriptul nostru pe linia 21. Deci, mai avem de făcut niște corecții de sintaxă.

Dacă ne uităm încă o dată prin scriptul analitic, eroarea de pe linia 21 se datorează lipsei ghilimelor duble de închidere ( ”) din ultima comandă echo din print_sys_info.

Vom adăuga ghilimele duble de închidere în comanda echo și vom salva fișierul. Scriptul modificat este mai jos:

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

Acum verificați sintactic scriptul încă o dată.

sudo bash -n sys_info.sh

Comanda de mai sus nu va produce niciun rezultat, deoarece scriptul nostru este acum corect din punct de vedere sintactic. De asemenea, putem urmări execuția scriptului pentru a doua oară și ar trebui să funcționeze bine:

sudo bash -x sys_info.sh

Acum rulați scriptul.

sudo ./sys_info.sh

Importanța urmăririi execuției scriptului Shell

Urmărirea scriptului Shell ne ajută să identificăm erorile de sintaxă și, mai important, erorile logice. Luați, de exemplu, funcția check_root din scriptul shell sys_info.sh, care are scopul de a determina dacă un utilizator este root sau nu, deoarece scriptul are voie doar să fie executat de către superutilizator.

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

Magia de aici este controlată de expresia if statement [ „$UID” -ne „$ROOT_ID” ], odată ce nu folosim operatorul numeric adecvat ( -ne în acest caz, ceea ce înseamnă nu este egal ), ajungem la o posibilă eroare logică.

Presupunând că am folosit -eq ( înseamnă egal cu), acest lucru ar permite oricărui utilizator de sistem, precum și utilizatorului root să ruleze scriptul, deci o eroare logică.

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

Notă: așa cum ne-am uitat la începutul acestei serii, comanda încorporată set shell poate activa depanarea într-o anumită secțiune a unui script shell.

Prin urmare, linia de mai jos ne va ajuta să găsim această eroare logică în funcție, urmărind execuția acesteia:

Scriptul cu o eroare logică:

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

Salvați fișierul și invocați scriptul, putem vedea că un utilizator obișnuit de sistem poate rula scriptul fără sudo, ca în rezultatul de mai jos. Acest lucru se datorează faptului că valoarea USER_ID este 100, care nu este egală cu rădăcină ROOT_ID, care este 0.

./sys_info.sh

Ei bine, asta este deocamdată, am ajuns la sfârșitul seriei de depanare a scripturilor shell, formularul de răspuns de mai jos poate fi folosit pentru a ne adresa orice întrebări sau feedback, cu privire la acest ghid sau întreaga serie din 3 părți.