debuggen van een Bash Script

overzicht

in deze tutorial zullen we kijken naar de verschillende technieken om Bash shell scripts te debuggen. De Bash shell biedt geen ingebouwde debugger. Er zijn echter bepaalde commando ‘ s en constructies die voor dit doel kunnen worden gebruikt.

eerst zullen we het gebruik van het set commando voor het debuggen van scripts bespreken. Daarna, We zullen controleren een paar debugging specifieke use-cases met behulp van de set en trap commando ‘ s. Tot slot zullen we enkele methoden presenteren om al draaiende scripts te debuggen.

Bash-Debugopties

de debugopties die beschikbaar zijn in de Bash-shell kunnen op meerdere manieren worden in-en uitgeschakeld. Binnen scripts kunnen we ofwel het set commando gebruiken of een optie Toevoegen aan de shebang regel. Echter, een andere aanpak is om expliciet de debugging opties in de opdrachtregel te specificeren tijdens het uitvoeren van het script. Laten we in de discussie duiken.

2.1. Enabling verbose Mode

we kunnen de verbose mode inschakelen met behulp van de-v switch, die ons in staat stelt om elk commando te bekijken voordat het wordt uitgevoerd.

om dit te demonstreren, maken we een voorbeeldscript:

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

dit script controleert of het ingevoerde nummer positief is.

laten we nu ons script uitvoeren:

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

zoals we kunnen zien, drukt het elke regel van het script af op de terminal voordat het wordt verwerkt.

we kunnen ook de-V optie in de shebang regel toevoegen:

#! /bin/bash -v

dit heeft hetzelfde effect als het expliciet aanroepen van een script met behulp van bash-v. Een ander equivalent is het inschakelen van de modus binnen een script met behulp van set commando:

#! /bin/bashset -v

in feite kunnen we een van de hierboven besproken manieren gebruiken om de verschillende switches in te schakelen die we voortaan zullen bespreken.

2.2. Syntaxiscontrole met noexec Mode

er kunnen situaties zijn waarin we het script syntactisch willen valideren voordat het wordt uitgevoerd. Als dat zo is, kunnen we de noexec modus gebruiken met de-n optie. Als gevolg hiervan zal Bash de commando ‘ s lezen, maar ze niet uitvoeren.

laten we onze positive_check.sh script in noexec-modus:

$ bash -n ./positive_check.sh

dit geeft een lege uitvoer omdat er geen syntaxisfouten zijn. Nu, we zullen ons script een beetje aanpassen en verwijderen van de dan statement:

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

vervolgens valideren we het syntactisch met de optie-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'

zoals verwacht, het gooide een fout omdat we de toen statement in de if conditie gemist.

2.3. Debugging met behulp van xtrace Mode

in de vorige sectie hebben we het script getest op syntaxisfouten. Maar voor het identificeren van logische fouten, willen we misschien de status van variabelen en commando ‘ s traceren tijdens het uitvoeringsproces. In dergelijke gevallen kunnen we het script in de modus xtrace (execution trace) uitvoeren met de optie-x.

deze modus drukt de trace van commando ‘ s voor elke regel af nadat ze zijn uitgevouwen, maar voordat ze worden uitgevoerd.

laten we onze positive_check.sh script in uitvoer-trace-modus:

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

hier kunnen we de uitgebreide versie van variabelen op stdout zien voor de uitvoering. Het is belangrijk op te merken dat de regels voorafgegaan door + teken worden gegenereerd door de xtrace mode.

2.4. Identificeren van niet-ingestelde variabelen

laten we een experiment uitvoeren om het standaardgedrag van niet-ingestelde variabelen in Bash-scripts te begrijpen:

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

we zullen nu het bovenstaande script uitvoeren:

$ ./add_values.sh5

zoals we kunnen zien, is er een probleem: het script is succesvol uitgevoerd, maar de uitvoer is logischerwijs onjuist.

we zullen nu het script uitvoeren met de-U optie:

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

zeker, er is veel meer duidelijkheid nu!

het script kon niet worden uitgevoerd omdat de variabele tow_val niet is gedefinieerd. We hadden ten onrechte getypt two_val als tow_val tijdens het berekenen van het totaal.

de optie-u behandelt niet-ingestelde variabelen en parameters als een fout bij het uitvoeren van parameteruitbreiding. Bijgevolg krijgen we een foutmelding dat een variabele niet aan waarde gebonden is tijdens het uitvoeren van het script met-u optie

Use Cases to Debug Shell Scripts

tot nu toe zagen we de verschillende switches voor debugging scripts. Voortaan zullen we kijken naar enkele use-cases en methoden om deze in shell scripts te implementeren.

3.1. Het combineren van Foutopsporingsopties

om betere inzichten te krijgen, kunnen we de verschillende opties van het set commando verder combineren.

laten we onze add_values.sh script met zowel-v als-u opties ingeschakeld:

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

door de uitgebreide modus met de optie-u in te schakelen, kunnen we gemakkelijk het statement identificeren dat de fout veroorzaakt.

evenzo kunnen we de uitgebreide en xtrace modus combineren om meer precieze debug informatie te krijgen.

zoals eerder besproken, toont de optie-v elke regel voordat deze wordt geëvalueerd, en de optie-x toont elke regel nadat ze zijn uitgevouwen. Daarom kunnen we zowel-x als-v opties combineren om te zien hoe statements eruit zien voor en na variabele substituties.

laten we nu onze positive_check.sh script met-x en-v-modus ingeschakeld:

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

we kunnen zien dat de statements worden afgedrukt op stdout voor en na variabele expansie.

3.2. Debuggen specifieke delen van het Script

debuggen met-x of-v optie shell scripts genereert een uitvoer voor elk statement op stdout. Er kunnen echter situaties zijn waarin we foutopsporingsinformatie willen beperken tot slechts specifieke delen van het script. We kunnen dat bereiken door de debug-modus in te schakelen voordat het codeblok begint, en het later opnieuw in te stellen met behulp van het set-commando.

laten we het controleren met een voorbeeld:

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

hier kunnen we alleen de IF-voorwaarde debuggen met behulp van het set-statement voordat de voorwaarde begint. Later kunnen we de xtrace-modus resetten nadat het if-blok eindigt met het set + x-Commando.

laten we het valideren met de uitvoer:

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

zeker, de output ziet er minder rommelig.

3.3. Alleen de Debug-uitvoer omleiden naar een bestand

in de vorige sectie hebben we onderzocht hoe we debugging kunnen beperken tot slechts bepaalde delen van het script. Bijgevolg kunnen we de hoeveelheid output op stdout beperken.

verder kunnen we de debug informatie omleiden naar een ander bestand en het script laten afdrukken op stdout.

laten we een ander script maken om het te controleren:

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

eerst hebben we de debug geopend.logbestand op File Descriptor (FD) 5 voor schrijven met behulp van het commando exec.

toen veranderden we de speciale shell variabele PS4. De PS4 variabele definieert de prompt die wordt weergegeven wanneer we een shell script in xtrace modus uit te voeren. De standaardwaarde van PS4 is +. We hebben de waarde van de PS4-variabele gewijzigd om regelnummers in de debugprompt weer te geven. Om dit te bereiken, gebruikten we een andere speciale shell variabele LINENO.

Later hebben we de FD 5 toegewezen aan bash variabele BASH_XTRACEFD. In feite zal Bash nu de xtrace-uitvoer schrijven op FD5 dwz debug.logboekbestand. Laten we het script uitvoeren:

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

zoals verwacht wordt de debug-uitvoer niet op de terminal geschreven. Hoewel, de eerste paar regels, totdat FD 5 is toegewezen aan debug output werden afgedrukt.

daarnaast maakt het script ook een debug-bestand aan.log, dat de debug informatie bevat:

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

debug-Scripts met trap

we kunnen de debug-trap-functie van Bash gebruiken om een opdracht herhaaldelijk uit te voeren. Het commando gespecificeerd in de argumenten van het trap commando wordt uitgevoerd voor elke volgende instructie in het script.

laten we dit illustreren met een voorbeeld:

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

In dit voorbeeld hebben we het echo Commando gespecificeerd om de waarden van de variabelen five_val, two_val en total af te drukken. Vervolgens hebben we dit echo statement doorgegeven aan het trap commando met het debug signaal. In feite, voorafgaand aan de uitvoering van elk commando in het script, worden de waarden van variabelen afgedrukt.

laten we de gegenereerde uitvoer controleren:

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

Debugging al draaiend Scripts

tot nu toe hebben we methoden gepresenteerd om shell scripts te debuggen tijdens het uitvoeren ervan. Nu, we zullen kijken naar manieren om een reeds draaiende script debuggen.

beschouw een voorbeeld draaiend script dat sleep uitvoert in een oneindige while loop:

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

met behulp van de pstree-opdracht kunnen we de dochterprocessen controleren die door ons script zijn gevorkt 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)

we gebruikten een extra optie-p om de proces-id ‘ s samen met de procesnamen af te drukken. Vandaar, We zijn in staat om te beseffen dat het script wacht op het kind processen (slaap) te voltooien.

soms willen we de bewerkingen die door onze processen worden uitgevoerd nader bekijken. In dergelijke gevallen kunnen we het strace commando gebruiken om de lopende Linux systeem aanroepen te traceren:

$ 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

hier gebruikten we de optie-p om aan het proces id (372) te koppelen, dat wil zeggen ons script in uitvoering. Daarnaast hebben we ook de optie-f gebruikt om aan al zijn dochterprocessen te koppelen. Merk op dat het strace Commando output genereert voor elke systeemaanroep. Daarom hebben we de optie-c gebruikt om een samenvatting van de systeemaanroepen af te drukken bij het beëindigen van strace.

conclusie

in deze tutorial hebben we meerdere technieken bestudeerd om een shell script te debuggen.

in het begin bespraken we de verschillende opties van set commando en hun gebruik voor debugging scripts. Daarna hebben we verschillende casestudy ‘ s geïmplementeerd om een combinatie van debugopties te bestuderen. Daarnaast hebben we ook manieren onderzocht om debug-uitvoer te beperken en om te leiden naar een ander bestand.

vervolgens presenteerden we een use-case van het trap commando en DEBUG signaal voor debug scenario ‘ s. Tot slot hebben we een paar benaderingen aangeboden om al draaiende scripts te debuggen.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.

Previous post Het trotseren van zijn koning: hoe de Slag bij Arsuf werd gewonnen
Next post Birds Eye View fotografie Tips