depanarea unui Script Bash

Prezentare generală

în acest tutorial, vom analiza diferitele tehnici de depanare a scripturilor bash shell. Shell-ul Bash nu oferă niciun depanator încorporat. Cu toate acestea, există anumite comenzi și construcții care pot fi utilizate în acest scop.

în primul rând, vom discuta despre utilizările comenzii set pentru scripturi de depanare. După aceea, vom verifica câteva cazuri de utilizare specifice de depanare folosind comenzile set și trap. În cele din urmă, vom prezenta câteva metode de depanare a scripturilor care rulează deja.

Opțiuni de depanare Bash

opțiunile de depanare disponibile în shell-ul Bash pot fi activate și dezactivate în mai multe moduri. În scripturi, putem folosi comanda set sau putem adăuga o opțiune la linia shebang. Cu toate acestea, o altă abordare este de a specifica în mod explicit opțiunile de depanare în linia de comandă în timpul executării scriptului. Să ne scufundăm în discuție.

2.1. Activarea modului verbose

putem activa modul verbose folosind comutatorul-v, care ne permite să vizualizăm fiecare comandă înainte de a fi executată.

pentru a demonstra acest lucru, să creăm un exemplu de script:

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

acest script verifică dacă numărul introdus ca intrare este pozitiv sau nu.

apoi, să executăm scenariul nostru:

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

după cum putem observa, imprimă fiecare linie a scriptului de pe terminal înainte de a fi procesată.

putem adăuga și opțiunea-v în linia shebang:

#! /bin/bash -v

acest lucru are același efect ca apelarea explicită a unui script folosind bash-v. Un alt echivalent este activarea modului într-un script folosind comanda set:

#! /bin/bashset -v

de fapt, putem folosi oricare dintre modalitățile discutate mai sus pentru a activa diferitele comutatoare pe care le vom discuta de acum înainte.

2.2. Verificarea sintaxei folosind modul noexec

pot exista situații în care este posibil să dorim să validăm scriptul sintactic înainte de executarea acestuia. Dacă da, putem folosi modul noexec folosind opțiunea-n. Drept urmare, Bash va citi comenzile, dar nu le va executa.

să ne executăm positive_check.sh script în modul noexec:

$ bash -n ./positive_check.sh

aceasta produce o ieșire goală, deoarece nu există erori de sintaxă. Acum, vom modifica scriptul nostru un pic și vom elimina Declarația de atunci:

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

apoi, o vom valida sintactic cu opțiunea-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'

așa cum era de așteptat, a aruncat o eroare, deoarece am ratat Declarația de atunci în condiția if.

2.3. Debugging folosind modul xtrace

în secțiunea anterioară, am testat scriptul pentru erori de sintaxă. Dar pentru identificarea erorilor logice, este posibil să dorim să urmărim starea variabilelor și comenzilor în timpul procesului de execuție. În astfel de cazuri, putem executa scriptul în modul xtrace (execution trace) folosind opțiunea-X.

acest mod imprimă urmele comenzilor pentru fiecare linie după ce sunt extinse, dar înainte de a fi executate.

să ne executăm positive_check.sh script în modul de urmărire a execuției:

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

aici putem vedea versiunea extinsă a variabilelor pe stdout înainte de execuție. Este important să rețineți că liniile precedate de semnul + sunt generate de modul xtrace.

2.4. Identificarea variabilelor nesetate

să rulăm un experiment pentru a înțelege comportamentul implicit al variabilelor nesetate în scripturile Bash:

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

vom executa acum scriptul de mai sus:

$ ./add_values.sh5

după cum putem observa, există o problemă: scriptul a fost executat cu succes, dar ieșirea este logic incorectă.

acum vom executa scriptul cu opțiunea-u:

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

cu siguranță, există mult mai multă claritate acum!

scriptul nu a reușit să execute deoarece variabila tow_val nu este definită. Am tastat din greșeală two_val ca tow_val în timp ce calculam totalul.

opțiunea-u tratează variabilele și parametrii nesetați ca o eroare la efectuarea expansiunii parametrilor. În consecință, primim o notificare de eroare că o variabilă nu este legată de valoare în timp ce executăm scriptul cu opțiunea-u

utilizați cazuri pentru a depana scripturile Shell

până acum, am văzut diferitele comutatoare pentru scripturile de depanare. De acum înainte, vom analiza câteva cazuri de utilizare și metode pentru a le implementa în scripturile shell.

3.1. Combinând opțiunile de depanare

pentru a obține informații mai bune, putem combina în continuare diferitele opțiuni ale comenzii set.

să ne executăm add_values.sh script cu ambele opțiuni-v și-u activate:

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

aici, activând modul detaliat cu opțiunea-u, am putea identifica cu ușurință instrucțiunea care declanșează eroarea.

în mod similar, putem combina modul verbose și xtrace pentru a obține informații de depanare mai precise.

după cum sa discutat anterior, opțiunea-v arată fiecare linie înainte de a fi evaluată, iar opțiunea-x arată fiecare linie după ce sunt extinse. Prin urmare, putem combina ambele opțiuni-x și-v pentru a vedea cum arată declarațiile înainte și după substituțiile variabile.

acum, să ne executăm positive_check.sh script cu modul-x și-v activat:

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

putem observa că declarațiile sunt tipărite pe stdout înainte și după expansiunea variabilă.

3.2. Debugging anumite părți ale Script-ul

Debugging cu-X sau-v script-uri shell opțiune generează o ieșire pentru fiecare declarație pe stdout. Cu toate acestea, pot exista situații în care este posibil să dorim să reducem informațiile de depanare doar la anumite părți ale scriptului. Putem realiza acest lucru activând modul de depanare înainte de începerea blocului de cod și apoi resetați-l folosind comanda set.

să o verificăm cu un exemplu:

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

aici, am putea depana numai condiția if folosind instrucțiunea set înainte de începerea condiției. Mai târziu, am putea reseta modul xtrace după ce blocul if se termină folosind comanda set + X.

să-l validăm cu ieșirea:

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

desigur, producția pare mai puțin aglomerată.

3.3. Redirecționând doar ieșirea de depanare către un fișier

în secțiunea anterioară, am examinat modul în care putem restricționa depanarea doar la anumite părți ale scriptului. În consecință, am putea restricționa cantitatea de producție pe stdout.

mai mult decât atât, putem redirecționa informațiile de depanare la un alt fișier și lăsați imprimarea de ieșire script pe stdout.

să creăm un alt script pentru a-l verifica:

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

în primul rând, am deschis depanarea.fișier jurnal pe Descriptor de fișiere (FD) 5 pentru scriere folosind comanda exec.

apoi am schimbat variabila specială shell PS4. Variabila PS4 definește promptul care se afișează atunci când executăm un script shell în modul xtrace. Valoarea implicită a PS4 este +. Am schimbat valoarea variabilei PS4 pentru a afișa numerele de linie în promptul de depanare. Pentru a realiza acest lucru, am folosit o altă variabilă specială shell LINENO.

mai târziu, am atribuit FD 5 variabilei Bash BASH_XTRACEFD. De fapt, Bash va scrie acum ieșirea xtrace pe FD5, adică depanare.fișier jurnal. Să executăm scriptul:

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

așa cum era de așteptat, ieșirea de depanare nu este scrisă pe terminal. Deși, primele câteva linii, până când FD 5 este atribuit debug de ieșire au fost tipărite.

în plus, scriptul creează, de asemenea, o depanare fișier de ieșire.jurnal, care conține informațiile de depanare:

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

Scripturi de depanare folosind trap

Putem utiliza caracteristica DEBUG trap din Bash pentru a executa o comandă în mod repetat. Comanda specificată în argumentele comenzii trap este executată înainte de fiecare declarație ulterioară din script.

să ilustrăm acest lucru cu un exemplu:

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

în acest exemplu, am specificat comanda echo pentru a imprima valorile variabilelor five_val, two_val și total. Ulterior, am transmis această declarație de ecou comenzii trap cu semnalul de depanare. De fapt, înainte de executarea fiecărei comenzi din script, valorile variabilelor sunt tipărite.

să verificăm ieșirea generată:

$ ./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 rulează deja Scripturi

până în prezent, am prezentat metode de depanare a scripturilor shell în timp ce le executăm. Acum, vom analiza modalități de depanare a unui script care rulează deja.

luați în considerare un exemplu de script care rulează care execută somnul într-o buclă infinită în timp ce:

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

cu ajutorul comenzii pstree, putem verifica procesele copil bifurcat de script-ul nostru 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)

am folosit o opțiune suplimentară-p pentru a imprima ID-urile procesului împreună cu numele procesului. Prin urmare, suntem capabili să realizăm că scenariul așteaptă ca procesele copilului (somnul) să se finalizeze.

uneori este posibil să dorim să aruncăm o privire mai atentă asupra operațiunilor efectuate de procesele noastre. În astfel de cazuri, putem folosi comanda strace pentru a urmări apelurile sistemului Linux în curs:

$ 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

aici am folosit opțiunea-p pentru a atașa la ID-ul procesului (372), adică scriptul nostru în execuție. În plus, am folosit și opțiunea-f pentru a atașa la toate procesele sale copil. Rețineți că, comanda strace generează ieșire pentru fiecare apel de sistem. Prin urmare, am folosit opțiunea-c pentru a imprima un rezumat al apelurilor de sistem la terminarea strace.

concluzie

în acest tutorial, am studiat mai multe tehnici pentru a depana un script shell.

la început, am discutat diferitele opțiuni de comandă set și utilizarea lor pentru script-uri de depanare. După aceea, am implementat mai multe studii de caz pentru a studia o combinație de opțiuni de depanare. Pe lângă aceasta, am explorat și modalități de a restricționa ieșirea de depanare și de a o redirecționa către un alt fișier.

în continuare, am prezentat un caz de utilizare a comenzii trap și a semnalului de depanare pentru scenarii de depanare. În cele din urmă, am oferit câteva abordări pentru depanarea Scripturilor care rulează deja.

Lasă un răspuns

Adresa ta de email nu va fi publicată.

Previous post Defying His King: cum a fost câștigată Bătălia de la Arsuf
Next post păsări ochi vedere Fotografie Sfaturi