Ladění Bash Skript

Přehled

V tomto tutoriálu, se podíváme na různé techniky ladění Bash shell skripty. Bash shell neposkytuje žádný vestavěný debugger. Existují však určité příkazy a konstrukce, které lze pro tento účel využít.

Nejprve budeme diskutovat o použití příkazu set pro ladění skriptů. Poté zkontrolujeme několik ladění konkrétních případů použití pomocí příkazů set a trap. Nakonec představíme některé metody ladění již spuštěných skriptů.

možnosti ladění Bash

možnosti ladění dostupné v prostředí Bash lze zapínat a vypínat několika způsoby. V rámci skriptů můžeme použít příkaz set nebo přidat možnost do řádku shebang. Dalším přístupem je však explicitně zadat možnosti ladění v příkazovém řádku při provádění skriptu. Pojďme se ponořit do diskuse.

2.1. Povolení Režimu s komentářem

můžeme zapnout verbose režimu pomocí přepínače-v, což nám umožňuje zobrazit každý příkaz, než bude popraven.

abychom to dokázali, vytvoříme ukázkový skript:

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

tento skript kontroluje, zda je číslo zadané jako vstup kladné.

Next, pojďme spustit náš skript:

$ 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.

Jak si můžeme všimnout, tiskne každý řádek skriptu na terminálu před tím, než je zpracována.

můžeme také přidat -v možnost v shebang řádek:

#! /bin/bash -v

To má stejný účinek jako explicitně volat skript pomocí bash -v. Další ekvivalentní je umožnit režim ve skriptu pomocí příkazu set:

#! /bin/bashset -v

ve skutečnosti můžeme použít některý z výše popsaných způsobů k povolení různých přepínačů, o kterých budeme dále diskutovat.

2.2. Kontrola syntaxe pomocí režimu noexec

mohou nastat situace, kdy budeme chtít ověřit skript syntakticky před jeho provedením. Pokud ano, můžeme použít režim noexec pomocí volby-n. Výsledkem je, že Bash přečte příkazy, ale neprovede je.

pojďme provést naše positive_check.sh skript v režimu noexec:

$ bash -n ./positive_check.sh

tím se vytvoří prázdný výstup, protože neexistují žádné chyby syntaxe. Nyní upravíme náš skript trochu a vyjměte pak prohlášení:

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

dále budeme ověřovat to syntakticky s parametrem-n:

$ 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'

očekává se, že to hodil chybu, co jsme vynechal, pak prohlášení v případě stavu.

2.3. Ladění pomocí režimu xtrace

v předchozí části jsme testovali skript na chyby syntaxe. Ale pro identifikaci logických chyb můžeme chtít sledovat stav proměnných a příkazů během procesu provádění. V takových případech můžeme skript spustit v režimu xtrace (execution trace) pomocí volby-x.

tento režim vytiskne stopu příkazů pro každý řádek po jejich rozbalení, ale před jejich provedením.

Pojďme vykonávat naše positive_check.sh skript v execution trace mode:

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

Zde můžeme vidět rozšířenou verzi proměnných na stdout před popravou. Je důležité si uvědomit, že řádky před znaménkem + jsou generovány režimem xtrace.

2.4. Identifikační Proměnné Unset

Pojďme spustit experiment, pochopit výchozí chování odstavení proměnných v Bash skripty:

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

Budeme nyní provést výše uvedený skript:

$ ./add_values.sh5

jak si můžeme všimnout, existuje problém: skript byl úspěšně proveden, ale výstup je logicky nesprávný.

nyní spustíme skript s volbou-u:

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

jistě, teď je mnohem jasnější!

skript se nepodařilo spustit, protože proměnná tow_val není definována. Při výpočtu součtu jsme omylem zadali two_val jako tow_val.

volba-u považuje unset proměnné a parametry za chybu při provádění rozšíření parametrů. V důsledku toho, dostaneme chybové oznámení, že proměnná není vázána na hodnotu, zatímco skriptu s volbou-u

Případy Použití Ladicí Shell Skripty

Tak daleko, viděli jsme různé přepínače pro ladění skriptů. Od této chvíle se podíváme na některé případy použití a metody jejich implementace do skriptů shellu.

3.1. Kombinace možností ladění

abychom získali lepší přehled, můžeme dále kombinovat různé možnosti příkazu set.

pojďme provést naše add_values.sh skript s aktivovanými možnostmi-v i-u:

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

zde, povolením podrobného režimu s volbou-u, bychom mohli snadno identifikovat příkaz spouštějící chybu.

podobně můžeme kombinovat režim verbose a xtrace, abychom získali přesnější informace o ladění.

Jak jsme se bavili dříve -v možnost ukazuje, každý řádek, než je hodnotí, a -x možnost ukazuje, každý řádek, poté se rozšířil. Proto můžeme kombinovat volby-x i-v, abychom viděli, jak vypadají příkazy před a po proměnných substitucích.

nyní provedeme naše positive_check.sh skript s povoleným režimem-x a-v:

$ 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.

můžeme pozorovat, že příkazy jsou vytištěny na stdout před a po rozšíření proměnné.

3.2. Ladění specifických částí skriptu

ladění pomocí skriptů-x nebo-v option shell generuje výstup pro každý příkaz na stdout. Mohou však nastat situace, kdy budeme chtít omezit informace o ladění pouze na konkrétní části skriptu. Můžeme toho dosáhnout tím, že umožňuje režim ladění před blok kódu začíná, a později obnovit pomocí příkazu set.

podívejme se na příklad:

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

zde bychom mohli ladit pouze podmínku if pomocí příkazu set před spuštěním podmínky. Později jsme mohli resetovat režim xtrace po ukončení bloku if pomocí příkazu set +x.

ověřme to výstupem:

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

jistě, výstup vypadá méně přeplněný.

3.3. Přesměrování pouze výstupu ladění do souboru

v předchozí části jsme zkoumali, jak můžeme omezit ladění pouze na určité části skriptu. V důsledku toho bychom mohli omezit množství výstupu na stdout.

dále můžeme přesměrovat informace o ladění do jiného souboru a nechat výstup skriptu vytisknout na stdout.

vytvoříme další skript, který to zkontroluje:

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

Nejprve jsme otevřeli ladění.soubor protokolu na deskriptoru souboru (FD) 5 pro zápis pomocí příkazu exec.

pak jsme změnili speciální shell proměnnou PS4. Proměnná PS4 definuje výzvu, která se zobrazí při spuštění skriptu shellu v režimu xtrace. Výchozí hodnota PS4 je +. Změnili jsme hodnotu proměnné PS4 tak, aby zobrazovala čísla řádků v řádku ladění. K dosažení tohoto cíle jsme použili další speciální shell variabilní LINENO.

později jsme FD 5 přiřadili Bash proměnné BASH_XTRACEFD. Ve skutečnosti Bash nyní zapíše výstup xtrace na FD5, tj.protokol. Pojďme spustit skript:

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

podle očekávání není výstup ladění zapsán na terminálu. I když, prvních několik řádků, dokud FD 5 je přiřazen k ladění výstupu byly vytištěny.

navíc skript také vytvoří ladění výstupního souboru.protokol, který obsahuje informace o ladění:

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

ladění skriptů pomocí trap

můžeme využít funkci DEBUG trap Bash k opakovanému spuštění příkazu. Příkaz zadaný v argumentech příkazu trap je proveden před každým následujícím příkazem ve skriptu.

vysvětleme si to na příkladu:

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

V tomto příkladu jsme zadali echo příkaz k tisku hodnot proměnných five_val, two_val, a celkem. Následně jsme tento příkaz echo předali příkazu trap s ladicím signálem. Ve skutečnosti se před provedením každého příkazu ve skriptu vytisknou hodnoty proměnných.

zkontrolujme vygenerovaný výstup:

$ ./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

ladění již spuštěných skriptů

zatím jsme představili metody ladění skriptů shellu při jejich provádění. Nyní se podíváme na způsoby ladění již spuštěného skriptu.

Zvažte vzorek běží skript, který provede spát v nekonečné smyčky while:

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

S pomocí pstree příkaz, můžeme zkontrolovat podřízené procesy vidlicový náš skript 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)

použili jsme další volbu-p pro tisk ID procesu spolu s názvy procesů. Proto jsme schopni si uvědomit, že skript čeká na dokončení podřízených procesů (spánku).

někdy se možná budeme chtít blíže podívat na operace prováděné našimi procesy. V takových případech můžeme pomocí příkazu strace sledovat probíhající volání systému Linux:

$ 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

zde jsme použili volbu-p pro připojení k ID procesu (372), tj. Kromě toho jsme také použili možnost-f pro připojení ke všem podřízeným procesům. Povšimněte si, že příkaz strace generuje výstup pro každé systémové volání. Proto jsme pomocí volby-c vytiskli souhrn systémových volání při ukončení strace.

závěr

v tomto tutoriálu jsme studovali několik technik pro ladění skriptu shellu.

na začátku jsme diskutovali různé možnosti příkazu set a jejich použití pro ladění skriptů. Poté jsme implementovali několik případových studií ke studiu kombinace možností ladění. Kromě toho jsme také prozkoumali způsoby, jak omezit výstup ladění a přesměrovat jej do jiného souboru.

dále jsme představili případ použití příkazu trap a ladicího signálu pro scénáře ladění. Nakonec jsme nabídli několik přístupů k ladění již spuštěných skriptů.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.

Previous post Vzpírat se Jeho Král: Jak Bitva u Arsufu Vyhrál
Next post Birds Eye View Photography tipy