Vyhledávání na webu

Jak sledovat provádění příkazů ve skriptu Shell pomocí funkce Shell Tracing


V tomto článku ze série ladění skriptů v prostředí vysvětlíme třetí režim ladění skriptů v prostředí, kterým je trasování prostředí, a podíváme se na několik příkladů, které demonstrují, jak funguje a jak jej lze použít.

Předchozí díl této série jasně vrhá světlo na dva další režimy ladění skriptů shellu: režim podrobného popisu a režim kontroly syntaxe se snadno srozumitelnými příklady, jak povolit shell ladění skriptů v těchto režimech.

  1. Jak povolit režim ladění skriptů Shell v Linuxu – část 1
  2. Jak provést režim ladění kontroly syntaxe ve skriptech Shell – část 2

Sledování prostředí jednoduše znamená sledování provádění příkazů ve skriptu shellu. Chcete-li zapnout sledování shellu, použijte volbu ladění -x.

To přikazuje shellu zobrazovat všechny příkazy a jejich argumenty na terminálu, když jsou prováděny.

Použijeme shellový skript sys_info.sh níže, který stručně vypíše datum a čas vašeho systému, počet přihlášených uživatelů a dobu provozu systému. Obsahuje však syntaktické chyby, které musíme najít a opravit.

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

Uložte soubor a vytvořte spustitelný skript. Skript může být spuštěn pouze uživatelem root, proto použijte příkaz sudo k jeho spuštění, jak je uvedeno níže:

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

Z výše uvedeného výstupu můžeme pozorovat, že příkaz je nejprve vykonán, než je jeho výstup nahrazen hodnotou proměnné.

Například date bylo poprvé provedeno a jeho výstup byl nahrazen hodnotou proměnné DATE.

Můžeme provést kontrolu syntaxe, abychom zobrazili pouze syntaktické chyby následovně:

sudo bash -n sys_info.sh 

Pokud se kriticky podíváme na skript shellu, uvědomíme si, že v příkazu if chybí závěrečné slovo fi. Proto jej přidejte a nový skript by nyní měl vypadat takto:

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

Uložte soubor znovu a vyvolejte jej jako root a proveďte nějakou kontrolu syntaxe:

sudo bash -n sys_info.sh

Výsledek naší operace kontroly syntaxe výše stále ukazuje, že v našem skriptu je na řádku 21 ještě jedna chyba. Musíme tedy ještě provést nějakou opravu syntaxe.

Pokud si skript prohlédneme analyticky ještě jednou, chyba na řádku 21 je způsobena chybějící dvojitou uvozovkou ( ”) v posledním příkazu echo uvnitř print_sys_info funkce.

Do příkazu echo přidáme závěrečnou dvojitou uvozovku a soubor uložíme. Změněný skript je níže:

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

Nyní syntakticky zkontrolujte skript ještě jednou.

sudo bash -n sys_info.sh

Výše uvedený příkaz neprodukuje žádný výstup, protože náš skript je nyní syntakticky správný. Můžeme také sledovat provádění skriptu podruhé a mělo by to fungovat dobře:

sudo bash -x sys_info.sh

Nyní spusťte skript.

sudo ./sys_info.sh

Význam trasování provádění skriptů Shell

Sledování skriptů shellu nám pomáhá identifikovat syntaktické chyby a co je důležitější, logické chyby. Vezměme si například funkci check_root v shell skriptu sys_info.sh, která je určena k určení, zda je uživatel root nebo ne, protože skript smí být pouze spuštěn. ze strany superuživatele.

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

Kouzlo zde řídí příkaz if výraz [ "$UID" -ne "$ROOT_ID" ], jakmile nepoužijeme vhodný číselný operátor ( -ne v tomto případě, což znamená nerovná se ), skončíme s možnou logickou chybou.

Za předpokladu, že jsme použili -eq ( znamená rovno), umožnilo by to spustit skript jakémukoli uživateli systému i uživateli root, takže logická chyba.

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

Poznámka: Jak jsme již uvedli na začátku této série, vestavěný příkaz set shell může aktivovat ladění v určité části skriptu shellu.

Proto nám řádek níže pomůže najít tuto logickou chybu ve funkci sledováním jejího provedení:

Skript s logickou chybou:

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

Uložte soubor a vyvolejte skript, vidíme, že běžný uživatel systému může skript spustit bez sudo, jak je uvedeno ve výstupu níže. Důvodem je, že hodnota USER_ID je 100, což se nerovná kořenovému ROOT_ID, což je 0.

./sys_info.sh

To je pro tuto chvíli vše, dostali jsme se na konec série ladění skriptů v shellu. Formulář odpovědí níže můžete použít k tomu, abyste nám adresovali jakékoli dotazy nebo zpětnou vazbu týkající se této příručky nebo celé 3dílné série.