felsökning av ett Bash-skript

översikt

i denna handledning tittar vi på de olika teknikerna för att felsöka Bash-skalskript. Bash-skalet ger ingen inbyggd debugger. Det finns dock vissa kommandon och konstruktioner som kan användas för detta ändamål.

först diskuterar vi användningarna av set-kommandot för felsökningsskript. Därefter kontrollerar vi några felsökningsspecifika användningsfall med hjälp av set-och trap-kommandona. Slutligen presenterar vi några metoder för att felsöka redan körda skript.

Bash felsökningsalternativ

felsökningsalternativen som finns i Bash-skalet kan slås på och av på flera sätt. Inom skript kan vi antingen använda kommandot set eller lägga till ett alternativ till shebang-raden. Ett annat tillvägagångssätt är dock att uttryckligen ange felsökningsalternativen i kommandoraden medan du kör skriptet. Låt oss dyka in i diskussionen.

2.1. Aktivera verbose Mode

vi kan aktivera verbose-läget med hjälp av-v-omkopplaren, vilket gör att vi kan se varje kommando innan det körs.

för att demonstrera detta, låt oss skapa ett exempelskript:

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

det här skriptet kontrollerar om numret som anges som inmatning är positivt eller inte.

Låt oss sedan utföra vårt manus:

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

som vi kan märka skriver den ut varje rad i skriptet på terminalen innan det bearbetas.

vi kan också lägga till-v-alternativet i shebang-raden:

#! /bin/bash -v

detta har samma effekt som att uttryckligen anropa ett skript med bash-v. En annan motsvarighet är att aktivera läget i ett skript med set-kommando:

#! /bin/bashset -v

faktum är att vi kan använda något av de sätt som diskuterats ovan för att aktivera de olika omkopplarna som vi kommer att diskutera framöver.

2.2. Syntaxkontroll med noexec-läge

det kan finnas situationer där vi kanske vill validera skriptet syntaktiskt innan det körs. Om så är fallet kan vi använda noexec-läget med alternativet-n. Som ett resultat kommer Bash att läsa kommandona men inte utföra dem.

låt oss utföra vår positive_check.sh skript i noexec-läge:

$ bash -n ./positive_check.sh

detta ger en tom utgång eftersom det inte finns några syntaxfel. Nu ändrar vi vårt skript lite och tar bort det dåvarande uttalandet:

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

därefter validerar vi det syntaktiskt med-n-alternativet:

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

som förväntat kastade det ett fel eftersom vi missade det dåvarande uttalandet i if-tillståndet.

2.3. Felsökning med xtrace-läge

i föregående avsnitt testade vi skriptet för syntaxfel. Men för att identifiera logiska fel kanske vi vill spåra tillståndet för variabler och kommandon under körningsprocessen. I sådana fall kan vi köra skriptet i xtrace (execution trace)- läge med alternativet-x.

det här läget skriver ut spår av kommandon för varje rad efter att de har expanderat men innan de körs.

låt oss utföra vår positive_check.sh script i exekveringsspårningsläge:

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

här kan vi se den utökade versionen av variabler på stdout före körning. Det är viktigt att notera att raderna som föregås av + – tecknet genereras av xtrace-läget.

2.4. Identifiera Unset-variabler

Låt oss köra ett experiment för att förstå standardbeteendet för unset-variabler i Bash-skript:

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

vi ska nu utföra ovanstående skript:

$ ./add_values.sh5

som vi kan märka finns det ett problem: skriptet körs framgångsrikt, men utmatningen är logiskt felaktig.

vi kör nu skriptet med alternativet-u:

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

Visst, det finns mycket mer tydlighet nu!

skriptet kunde inte köras eftersom variabeln tow_val inte är definierad. Vi hade felaktigt skrivit two_val som tow_val medan vi beräknade summan.

alternativet-u behandlar oinställda variabler och parametrar som ett fel vid parameterutvidgning. Följaktligen får vi ett felmeddelande om att en variabel inte är bunden till värde när du kör skriptet med-U-alternativet

Använd fall för att felsöka skalskript

hittills såg vi de olika omkopplarna för felsökningsskript. Hädanefter kommer vi att titta på några användningsfall och metoder för att implementera dessa i skalskript.

3.1. Kombinera felsökningsalternativ

för att få bättre insikter kan vi ytterligare kombinera de olika alternativen för set-kommandot.

låt oss utföra vår add_values.sh skript med både-v och-u-alternativ aktiverade:

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

här, genom att aktivera verbose-läget med-u-alternativet, kan vi enkelt identifiera uttalandet som utlöser felet.

på samma sätt kan vi kombinera verbose och xtrace-läget för att få mer exakt felsökningsinformation.

som diskuterats tidigare visar-v-alternativet varje rad innan den utvärderas och-x-alternativet visar varje rad efter att de har expanderats. Därför kan vi kombinera både-x och-v alternativ för att se hur uttalanden ser ut före och efter variabla substitutioner.

nu, låt oss utföra vår positive_check.sh skript med-x och-v-läge aktiverat:

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

vi kan observera att uttalandena skrivs ut på stdout före och efter variabel expansion.

3.2. Felsökning specifika delar av skriptet

felsökning med-x eller-v alternativet skalskript genererar en utgång för varje uttalande på stdout. Det kan dock finnas situationer där vi kanske vill minska felsökningsinformation till endast specifika delar av skriptet. Vi kan uppnå det genom att aktivera felsökningsläget innan kodblocket startar och senare återställa det med kommandot set.

låt oss kolla det med ett exempel:

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

här kan vi bara felsöka if-villkoret med set-satsen innan villkoret startar. Senare kunde vi återställa xtrace-läget efter att if-blocket slutar med kommandot set +x.

låt oss validera det med utgången:

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

visst ser utmatningen mindre rörig ut.

3.3. Omdirigera endast Felsökningsutmatningen till en fil

i föregående avsnitt undersökte vi hur vi kan begränsa felsökning till endast vissa delar av skriptet. Följaktligen kan vi begränsa mängden produktion på stdout.

Dessutom kan vi omdirigera felsökningsinformationen till en annan fil och låta skriptet skriva ut på stdout.

Låt oss skapa ett annat skript för att kontrollera det:

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

först öppnade vi felsökningen.loggfil på Filbeskrivning (FD) 5 för skrivning med exec-kommandot.

sedan ändrade vi den speciella skalvariabeln PS4. PS4-variabeln definierar prompten som visas när vi kör ett skalskript i xtrace-läge. Standardvärdet för PS4 är +. Vi ändrade värdet på PS4-variabeln för att visa radnummer i felsökningsprompten. För att uppnå detta använde vi en annan speciell skalvariabel LINENO.

senare tilldelade vi fd 5 till Bash-variabeln BASH_XTRACEFD. I själva verket kommer Bash nu att skriva xtrace-utgången på FD5, dvs debug.loggfil. Låt oss köra manuset:

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

som förväntat skrivs inte felsökningsutgången på terminalen. Även om de första raderna, tills FD 5 tilldelas felsökningsutmatning, skrivs ut.

dessutom skapar skriptet också en felsökningsfil.logg, som innehåller felsökningsinformationen:

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

Felsökningsskript med trap

vi kan använda funktionen DEBUG trap i Bash för att utföra ett kommando repetitivt. Kommandot som anges i argumenten för trap-kommandot körs före varje efterföljande uttalande i skriptet.

låt oss illustrera detta med ett exempel:

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

i det här exemplet angav vi echo-kommandot för att skriva ut värdena för variablerna five_val, two_val och total. Därefter passerade vi detta echo-uttalande till trap-kommandot med FELSÖKNINGSSIGNALEN. I själva verket, före utförandet av varje kommando i skriptet, skrivs värdena på variabler ut.

låt oss kontrollera den genererade utgången:

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

felsökning redan kör skript

hittills presenterade vi metoder för att felsöka skalskript medan du kör dem. Nu ska vi titta på sätt att felsöka ett redan löpande skript.

Tänk på ett exempel som kör skript som kör sömn i en oändlig loop:

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

med hjälp av pstree-kommandot kan vi kontrollera barnprocesserna som gafflas av vårt manus 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)

vi använde ett extra alternativ-p för att skriva ut process-id tillsammans med processnamnen. Därför kan vi inse att manuset väntar på att barnprocesserna (sömn) ska slutföras.

ibland kanske vi vill titta närmare på de operationer som utförs av våra processer. I sådana fall kan vi använda strace-kommandot för att spåra pågående Linux-systemanrop:

$ 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

här använde vi alternativet-p för att bifoga process-id (372), dvs vårt skript i körning. Dessutom använde vi också-F-alternativet för att bifoga alla dess barnprocesser. Observera att kommandot strace genererar utdata för varje systemanrop. Därför använde vi alternativet-c för att skriva ut en sammanfattning av systemanrop vid uppsägning av strace.

slutsats

i denna handledning studerade vi flera tekniker för att felsöka ett skalskript.

i början diskuterade vi de olika alternativen för set command och deras användning för felsökningsskript. Därefter genomförde vi flera fallstudier för att studera en kombination av felsökningsalternativ. Vid sidan av detta undersökte vi också sätt att begränsa felsökningsutmatning och omdirigera den till en annan fil.

därefter presenterade vi ett användningsfall av trap-kommandot och FELSÖKNINGSSIGNALEN för felsökningsscenarier. Slutligen erbjöd vi några sätt att felsöka redan körda skript.

Lämna ett svar

Din e-postadress kommer inte publiceras.

Previous post Trotsar sin kung: hur slaget vid Arsuf vann
Next post Birds Eye View Photography Tips