Bash szkript hibakeresése

áttekintés

ebben az oktatóanyagban megvizsgáljuk a Bash shell szkriptek hibakeresésének különféle technikáit. A Bash shell nem nyújt beépített hibakeresőt. Vannak azonban bizonyos parancsok és konstrukciók, amelyeket erre a célra lehet használni.

először a set parancs hibakeresési parancsainak használatát tárgyaljuk. Ezt követően néhány hibakeresési konkrét felhasználási esetet ellenőrizünk a set and trap parancsok segítségével. Végül bemutatunk néhány módszert a már futó szkriptek hibakeresésére.

Bash hibakeresési lehetőségek

a Bash shell hibakeresési lehetőségei többféle módon be-és kikapcsolhatók. A szkripteken belül használhatjuk a set parancsot, vagy hozzáadhatunk egy opciót a shebang sorhoz. Egy másik megközelítés azonban a hibakeresési lehetőségek kifejezett megadása a parancssorban a parancsfájl végrehajtása közben. Merüljünk bele a vitába.

2.1. A verbose mód engedélyezése

a verbose módot a-v kapcsolóval engedélyezhetjük, amely lehetővé teszi az egyes parancsok megtekintését a végrehajtás előtt.

ennek bemutatásához hozzunk létre egy minta szkriptet:

#! /bin/bashread -p "Enter the input: " valzero_val=0if then echo "Positive number entered."else echo "The input value is not positive."fi

ez a parancsfájl ellenőrzi, hogy a bemenetként megadott szám pozitív-e vagy sem.

ezután hajtsuk végre a szkriptünket:

$ bash -v ./positive_check.sh#! /bin/bashread -p "Enter the input: " valEnter the input: -10zero_val=0if then echo "Positive number entered."else echo "The input value is not positive."fiThe input value is not positive.

amint észrevehetjük, kinyomtatja a szkript minden sorát a terminálon, mielőtt feldolgoznák.

hozzáadhatjuk a-v opciót is a shebang sorban:

#! /bin/bash -v

ennek ugyanaz a hatása, mint egy szkript explicit meghívása a bash-V használatával. egy másik egyenértékű az, hogy engedélyezzük a szkripten belüli módot a set paranccsal:

#! /bin/bashset -v

valójában a fent tárgyalt módok bármelyikét használhatjuk a különféle kapcsolók engedélyezéséhez, amelyeket a továbbiakban megvitatunk.

2.2. Szintaxisellenőrzés a noexec mód használatával

előfordulhatnak olyan helyzetek, amikor a szkriptet szintaktikailag érvényesíteni kell a végrehajtása előtt. Ha igen, akkor a noexec módot használhatjuk a-n opcióval. Ennek eredményeként a Bash elolvassa a parancsokat, de nem hajtja végre őket.

hajtsuk végre a positive_check.sh szkript noexec módban:

$ bash -n ./positive_check.sh

ez üres kimenetet eredményez, mivel nincsenek szintaktikai hibák. Most egy kicsit módosítjuk a szkriptünket, majd eltávolítjuk a then utasítást:

#! /bin/bashread -p "Enter the input: " valzero_val=0if echo "Positive number entered."else echo "The input value is not positive."fi

ezután szintaktikailag érvényesítjük a-n opcióval:

$ bash -n ./positive_check_noexec.sh./positive_check_noexec.sh: line 6: syntax error near unexpected token `else'./positive_check_noexec.sh: line 6: ` else'

ahogy az várható volt, hibát dobott, mivel elmulasztottuk a then állítást az if állapotban.

2.3. Hibakeresés Xtrace módban

az előző szakaszban teszteltük a szkriptet szintaktikai hibák szempontjából. De a logikai hibák azonosításához érdemes nyomon követni a változók és parancsok állapotát a végrehajtási folyamat során. Ilyen esetekben a szkriptet xtrace (execution trace) módban hajthatjuk végre a-x opcióval.

ez a mód kinyomtatja a parancsok nyomát az egyes sorokhoz a kibontás után, de a végrehajtás előtt.

hajtsuk végre a positive_check.sh script végrehajtás nyomkövetési módban:

$ bash -x ./positive_check.sh+ read -p 'Enter the input: ' valEnter the input: 17+ zero_val=0+ ''+ echo 'Positive number entered.'Positive number entered.

itt láthatjuk a változók kibővített változatát az stdout-on a végrehajtás előtt. Fontos megjegyezni, hogy a + jel előtti sorokat az xtrace mód generálja.

2.4. A nem beállított változók azonosítása

futtassunk egy kísérletet a nem beállított változók alapértelmezett viselkedésének megértéséhez a Bash szkriptekben:

#! /bin/bashfive_val=5two_val=2total=$((five_val+tow_val))echo $total

most végrehajtjuk a fenti szkriptet:

$ ./add_values.sh5

amint észrevehetjük, van egy probléma: a szkript sikeresen végrehajtott, de a kimenet logikailag helytelen.

most végrehajtjuk a szkriptet a-u opcióval:

$ bash -u ./add_values.sh./add_values.sh: line 4: tow_val: unbound variable

természetesen most sokkal több a tisztánlátás!

a parancsfájl végrehajtása nem sikerült, mivel a tow_val változó nincs definiálva. Mi volt tévesen gépelt two_val mint tow_val kiszámításakor a teljes.

a-u opció hibaként kezeli a nem beállított változókat és paramétereket a paraméterbővítés végrehajtásakor. Következésképpen hibaüzenetet kapunk arról, hogy egy változó nem kötődik az értékhez, miközben a szkriptet a-u opcióval hajtja végre

esetek használata Shell szkriptek hibakereséséhez

eddig láttuk a szkriptek hibakeresésének különféle kapcsolóit. A továbbiakban megvizsgálunk néhány felhasználási esetet és módszert ezek implementálására shell szkriptekben.

3.1. A hibakeresési lehetőségek kombinálása

a jobb betekintés érdekében tovább kombinálhatjuk a set parancs különféle lehetőségeit.

hajtsuk végre a add_values.sh szkript mind a-v, mind az-u opcióval engedélyezve:

$ bash -uv ./add_values.sh#! /bin/bashfive_val=5two_val=2total=$((five_val+tow_val))./add_values.sh: line 4: tow_val: unbound variable

itt a részletes mód engedélyezésével a-u opcióval könnyen azonosíthatjuk a hibát kiváltó utasítást.

hasonlóképpen kombinálhatjuk a részletes és az xtrace módot, hogy pontosabb hibakeresési információkat kapjunk.

amint azt korábban tárgyaltuk, a-v opció az egyes sorokat az értékelés előtt, az-x opció pedig az egyes sorokat a kibontás után jeleníti meg. Ezért kombinálhatjuk mind az-x, mind a-v opciókat, hogy lássuk, hogyan néznek ki az állítások a változó helyettesítések előtt és után.

most hajtsuk végre a positive_check.sh script-x és-v mód engedélyezve:

$ bash -xv ./positive_check.sh#! /bin/bashread -p "Enter the input: " val+ read -p 'Enter the input: ' valEnter the input: 5zero_val=0+ zero_val=0if then echo "Positive number entered."else echo "The input value is not positive."fi+ ''+ echo 'Positive number entered.'Positive number entered.

megfigyelhetjük, hogy az utasítások az stdout-ra vannak nyomtatva a változó bővítése előtt és után.

3.2. A parancsfájl egyes részeinek hibakeresése

hibakeresés-x vagy-v opcióval shell szkriptek kimenetet generál az stdout minden utasításához. Előfordulhatnak azonban olyan helyzetek, amikor a hibakeresési információkat csak a szkript meghatározott részeire szeretnénk csökkenteni. Ezt úgy érhetjük el, hogy engedélyezzük a hibakeresési módot a kódblokk megkezdése előtt, majd később visszaállítjuk a set paranccsal.

nézzük meg egy példával:

#! /bin/bashread -p "Enter the input: " valzero_val=0set -xif then echo "Positive number entered."else echo "The input value is not positive."fiset +xecho "Script Ended" 

itt csak az if feltételt tudtuk hibakeresni a set utasítás használatával a feltétel megkezdése előtt. Később visszaállíthatjuk az xtrace módot, miután az if blokk véget ért a set + x paranccsal.

érvényesítsük a kimenettel:

$ ./positive_debug.shEnter the input: 7+ ''+ echo 'Positive number entered.'Positive number entered.+ set +xScript Ended

természetesen a kimenet kevésbé rendetlennek tűnik.

3.3. Csak a hibakeresési kimenet átirányítása egy fájlba

az előző szakaszban megvizsgáltuk, hogyan korlátozhatjuk a hibakeresést a szkript bizonyos részeire. Következésképpen korlátozhatjuk az stdout kimenetének mennyiségét.

ezenkívül átirányíthatjuk a hibakeresési információkat egy másik fájlba, és hagyhatjuk, hogy a szkript kimenete az stdout-on nyomtasson.

hozzunk létre egy másik szkriptet annak ellenőrzéséhez:

#! /bin/bashexec 5> debug.log PS4='$LINENO: ' BASH_XTRACEFD="5" read -p "Enter the input: " valzero_val=0if then echo "Positive number entered."else echo "The input value is not positive."fi

először megnyitottuk a hibakeresést.naplófájl a Fájlleíróban (FD) 5 az exec paranccsal történő íráshoz.

ezután megváltoztattuk a PS4 speciális héjváltozót. A PS4 változó meghatározza azt a promptot, amely akkor jelenik meg, amikor egy shell szkriptet futtatunk xtrace módban. A PS4 alapértelmezett értéke +. Megváltoztattuk a PS4 változó értékét, hogy a sorszámokat megjelenítsük a hibakeresési promptban. Ennek eléréséhez egy másik speciális héjváltozót használtunk LINENO.

később hozzárendeltük az FD 5 to bash változót BASH_XTRACEFD. Valójában a Bash most az xtrace kimenetet írja az FD5-re, azaz hibakeresésre.naplófájl. Hajtsuk végre a szkriptet:

$ bash -x ./debug_logging.sh+ exec+ PS4='$LINENO: '4: BASH_XTRACEFD=5Enter the input: 2Positive number entered.

ahogy az várható volt, a hibakeresési kimenetet nem írják a terminálra. Bár, az első néhány sort, amíg FD 5 van rendelve hibakeresés kimenet nyomtatták.

ezenkívül a szkript létrehoz egy kimeneti fájl hibakeresést is.napló, amely tartalmazza a hibakeresési információkat:

$ cat debug.log5: read -p 'Enter the input: ' val6: zero_val=07: ''9: echo 'Positive number entered.'

hibakeresés szkriptek használata trap

tudjuk használni a DEBUG trap funkció Bash, hogy végre egy parancsot ismétlődően. A trap parancs argumentumaiban megadott parancs a parancsfájl minden további utasítása előtt végrehajtásra kerül.

illusztráljuk ezt egy példával:

#! /bin/bashtrap 'echo "Line- ${LINENO}: five_val=${five_val}, two_val=${two_val}, total=${total}" ' DEBUGfive_val=5two_val=2total=$((five_val+two_val))echo "Total is: $total"total=0 && echo "Resetting Total"

ebben a példában megadtuk az echo parancsot a five_val, two_val és total változók értékeinek kinyomtatására. Ezt követően átadtuk ezt az echo nyilatkozatot a trap parancsnak a hibakeresési jelzéssel. Valójában a parancsfájl minden parancsának végrehajtása előtt a változók értékei kinyomtatásra kerülnek.

ellenőrizzük a generált kimenetet:

$ ./trap_debug.shLine- 3: five_val=, two_val=, total=Line- 4: five_val=5, two_val=, total=Line- 5: five_val=5, two_val=2, total=Line- 6: five_val=5, two_val=2, total=7Total is: 7Line- 7: five_val=5, two_val=2, total=7Line- 7: five_val=5, two_val=2, total=0Resetting Total

hibakeresés már futó szkriptek

eddig bemutattunk módszereket a shell szkriptek hibakeresésére azok végrehajtása közben. Most megvizsgáljuk a már futó szkript hibakeresésének módjait.

Vegyünk egy minta futó szkriptet, amely végrehajtja az alvást egy végtelen while ciklusban:

#! /bin/bashwhile :do sleep 10 & echo "Sleeping for 4 seconds.." sleep 4done

a pstree parancs segítségével ellenőrizhetjük a szkriptünk által elágazó gyermekfolyamatokat sleep.sh:

$ pstree -pinit(1)─┬─init(148)───bash(149)───sleep.sh(372)─┬─sleep(422) │ ├─sleep(424) │ └─sleep(425) ├─init(213)───bash(214)───pstree(426) └─{init}(7)

egy további opciót használtunk-p a folyamatazonosítók nyomtatásához a folyamatnevekkel együtt. Ezért képesek vagyunk felismerni, hogy a szkript arra vár, hogy a gyermek folyamatai (alvás) befejeződjenek.

néha érdemes közelebbről megvizsgálni a folyamataink által végrehajtott műveleteket. Ilyen esetekben a strace paranccsal nyomon követhetjük a folyamatban lévő Linux rendszerhívásokat:

$ sudo strace -c -fp 372strace: Process 372 attachedstrace: Process 789 attachedstrace: Process 790 attached^Cstrace: Process 372 detachedstrace: Process 789 detachedstrace: Process 790 detached% time seconds usecs/call calls errors syscall------ ----------- ----------- --------- --------- ----------------100.00 0.015625 5208 3 wait4 0.00 0.000000 0 6 read 0.00 0.000000 0 1 write 0.00 0.000000 0 39 close 0.00 0.000000 0 36 fstat 0.00 0.000000 0 38 mmap 0.00 0.000000 0 8 mprotect 0.00 0.000000 0 2 munmap 0.00 0.000000 0 6 brk 0.00 0.000000 0 16 rt_sigaction 0.00 0.000000 0 20 rt_sigprocmask 0.00 0.000000 0 1 rt_sigreturn 0.00 0.000000 0 6 6 access 0.00 0.000000 0 1 dup2 0.00 0.000000 0 2 getpid 0.00 0.000000 0 2 clone 0.00 0.000000 0 2 execve 0.00 0.000000 0 2 arch_prctl 0.00 0.000000 0 37 openat------ ----------- ----------- --------- --------- ----------------100.00 0.015625 228 6 total

itt a-p opciót használtuk a folyamatazonosítóhoz (372), azaz a szkriptünk végrehajtásához. Ezenkívül a-f opciót is használtuk az összes gyermekfolyamathoz való csatoláshoz. Vegye figyelembe, hogy a strace parancs minden rendszerhíváshoz kimenetet generál. Ezért a-c opciót használtuk a rendszerhívások összefoglalójának kinyomtatására a strace befejezésekor.

következtetés

ebben az oktatóanyagban több technikát tanulmányoztunk egy shell szkript hibakeresésére.

kezdetben megvitattuk a set parancs különböző lehetőségeit és a szkriptek hibakeresésének használatát. Ezt követően számos esettanulmányt hajtottunk végre a hibakeresési lehetőségek kombinációjának tanulmányozására. Emellett azt is megvizsgáltuk, hogyan lehet korlátozni a hibakeresési kimenetet, és átirányítani egy másik fájlba.

ezután bemutattuk a trap parancs és a DEBUG signal használatát a hibakeresési forgatókönyvekhez. Végül felajánlottunk néhány megközelítést a már futó szkriptek hibakeresésére.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.

Previous post Dacolva a királyával: hogyan nyerték meg az Arsuf-i csatát
Next post Birds Eye View Photography tippek