Cum se depanează un script bash?

Am unele probleme cu unele scripturi în bash, despre erori și comportamente neașteptate. Aș dori să investighez cauzele problemelor, astfel încât să pot aplica remedieri. Există o modalitate prin care pot transforma un fel de „mod de depanare” pentru bash, pentru a obține mai multe informații?

Răspuns

Porniți scriptul bash cu bash -x ./script.sh sau adăugați în scriptul dvs. set -x pentru a vedea ieșirea de depanare.


Suplimentar cu bash 4.1 sau o versiune ulterioară:

Dacă doriți să scrieți ieșirea de depanare într-un fișier separat, adăugați acest lucru la script:

exec 5> debug_output.txt BASH_XTRACEFD="5" 

Vedeți: https://stackoverflow.com/a/25593226/3776858


Dacă doriți să vedeți numerele de linie adăugați acest lucru:

PS4="$LINENO: " 


Dacă aveți acces la apoi o puteți utiliza pentru a scrie ieșirea de depanare prin syslog-ul dvs. cu timestamp, numele scriptului și numărul liniei:

#!/bin/bash exec 5> >(logger -t $0) BASH_XTRACEFD="5" PS4="$LINENO: " set -x # Place your code here 

Puteți utiliza opțiunea -p din comanda logger pentru a seta o facilitate și un nivel individual să scrie ieșire prin syslog local în propriul său fișier jurnal.

Comentarii

  • -v poate ajuta și (imprimă fiecare linie pe măsură ce sunt executate. poate fi combinat cu -x). Și vedeți și: bashdb.sourceforge.net
  • o altă resursă minunată este: shellcheck .net
  • Ce înseamnă ” exec 5 > ” do?
  • @aggsol: Dacă utilizați BASH_XTRACEFD="5" bash scrie rezultatul urmăririi generate atunci când set -x este activat pentru descriptor de fișier 5. exec 5> >(logger -t $0) redirecționează ieșirea din descriptorul de fișier 5 către logger comanda.
  • Vă întrebați doar puteți obține numărul liniei și calea scriptului shell sau numele în PS4?

Răspundeți

Folosind set -x

folosesc întotdeauna set -x și set +x. Puteți înfășura zone care doriți să vedeți ce se întâmplă cu ele pentru a transforma verbositatea în sus / în jos.

#!/bin/bash set -x ..code to debug... set +x 

log4bash

De asemenea dacă ați terminat munca de dezvoltare și sunteți familiarizați cu stilul loggerilor care poartă numele log4j, log4perl etc., atunci vă recomandăm să utilizați log4bash .

extras

Să ne confruntăm – ecoul vechi simplu nu îl tăie. log4bash este o încercare de a avea o înregistrare mai bună pentru scripturile Bash (adică faceți logarea în Bash suge mai puțin).

De acolo puteți face astfel de lucruri în Scripturi Bash:

#!/usr/bin/env bash source log4bash.sh log "This is regular log message... log and log_info do the same thing"; log_warning "Luke ... you turned off your targeting computer"; log_info "I have you now!"; log_success "You"re all clear kid, now let"s blow this thing and go home."; log_error "One thing"s for sure, we"re all gonna be a lot thinner."; # If you have figlet installed -- you"ll see some big letters on the screen! log_captains "What was in the captain"s toilet?"; # If you have the "say" command (e.g. on a Mac) log_speak "Resistance is futile"; 

Rezultând acest tip de ieșire:

        ss1

log4sh

Dacă aveți nevoie de ceva mai portabil, există și mai vechi log4sh. Funcționează similar cu log4bash, disponibil aici:

Comentarii

  • Pe Ubuntu, am alias say="spd-say" în .bashrc, care imită say de la alte distribuții sau OS X.
  • set -vx ar fi o combinație bună dacă este utilizat cu trap – trap read debug. Acest lucru vă permite să treceți peste linie cu linie și vezi rezultatele

Răspuns

Există „un depanator bash, bashdb , care este un pachet instalabil pe multe distribuții. Folosește modul de depanare extins încorporat al lui bash (shopt -s extdebug). Seamănă foarte mult cu gdb; aici este o sesiune de eșantionare pentru a da o anumită aromă:

$ ls 1st.JPG 2ndJPG.JPG $ cat ../foo.sh for f in *.JPG do newf=${f/JPG/jpg} mv $f $newf done $ bashdb ../foo.sh (foo.sh:1): 1: for f in *.JPG bashdb<0> next (foo.sh:3): 3: newf=${f/JPG/jpg} bashdb<1> next (foo.sh:4): 4: mv $f $newf 

La fel ca în gdb, declarația este afișată chiar înainte este pe cale să fie executată. Așadar, putem examina variabile pentru a vedea ce va face declarația înainte de ao face.

bashdb<2> print $f $newf 1st.JPG 1st.jpg bashdb<3> next (foo.sh:1): 1: for f in *.JPG bashdb<4> next (foo.sh:3): 3: newf=${f/JPG/jpg} bashdb<5> next (foo.sh:4): 4: mv $f $newf bashdb<6> print $f $newf 2ndJPG.JPG 2ndjpg.JPG 

Asta nu este ceea ce vrem! Să privim extinderea parametrilor din nou.

bashdb<7> print $f ${f/JPG/jpg} 2ndJPG.JPG 2ndjpg.JPG bashdb<8> print $f ${f/JPG$/jpg} 2ndJPG.JPG 2ndJPG.JPG bashdb<9> print $f ${f/%JPG/jpg} 2ndJPG.JPG 2ndJPG.jpg 

OK, asta funcționează. Să „setăm newf la valoarea corectă.

bashdb<10> eval newf=${f/%JPG/jpg} $? is 0 bashdb<11> print $f $newf 2ndJPG.JPG 2ndJPG.jpg 

Arată bine. Continuați scriptul.

bashdb<12> next Debugged program terminated normally. Use q to quit or R to restart. $ ls 1st.jpg 2ndJPG.jpg 

Răspuns

Metoda standard pentru depanarea scripturilor în majoritatea shell-urilor bazate pe Bourne, cum ar fi bash este să scrieți set -x în partea de sus a scriptului dvs. Acest lucru va face bash mai detaliat despre ceea ce se face / se execută și despre modul în care argumentele sunt evaluate.

-x Print commands and their arguments as they are executed. 

acest lucru este util fie pentru interpret, fie pentru scripturile din interior. De exemplu:

$ find "$fileloc" -type f -prune "$filename" -print + find /var/adm/logs/morelogs -type f -prune "-name *.user" -print find: unknown predicate "-name *.user" $ find "$fileloc" -type f -prune $filename -print + find /var/adm/logs/morelogs -type f -prune -name "*.user" -print find: "/var/adm/logs/morelogs": No such file or directory 

În cele de mai sus putem vedea de ce nu se găsește găsirea datorită unor ghilimele unice.

Pentru a dezactiva caracteristica, trebuie doar să tastați set +x.

Răspuns

Utilizarea Eclipse

Puteți utiliza mediul combinat Eclipse și Shelled cu scriptul „_DEBUG.sh” legat mai jos.

Comutarea shell-urilor

De În mod implicit, instrumentul de dezvoltare Shelled folosește /bin/dash ca interpret. Am schimbat acest lucru în /bin/bash pentru a avea o compatibilitate mai bună cu majoritatea exemplelor de shell de pe web și mediul meu.

NOTĂ: Puteți schimba acest lucru accesând: Window -> Preferință -> Shell Script -> Interpreti

Instrucțiuni de configurare

Pachetul Debugger conține pașii pentru utilizarea scriptului _DEBUG.sh pentru depanarea scriptului, care este practic (readme.txt):

  1. Creați un proiect Shell Script: Fișier -> Nou -> Altele – > Script Shell

-> Expertul de proiect Shell Script .

  • Creați un fișier script Bash: Fișier -> Nou -> Fișier . Pentru acest exemplu, va fi script.sh. Extensia trebuie să fie „.sh” și este obligatorie.
  • Copiați fișierul _DEBUG.sh în dosarul proiectului.
  • Introduceți fișierul textul următor în partea de sus a fișierului script.sh:

    . _DEBUG.sh 
  • Dacă fișierul este creat în Microsoft Windows, apoi asigurați-vă că executați Fișier -> Conversia delimitatorilor de linie în -> Unix .

  • Configurați o configurație de lansare a depanării: Rulați -> Configurări de depanare -> Script Bash … Există 2 câmpuri de setat aici:

    a) „Script Bash:” – Calea din spațiul de lucru Eclipse către scriptul Bash pentru depanare.
    e) „Port de depanare:” 33333

  • Comută la perspectiva Debug. Porniți sesiunea de depanare. Lansați script.sh din bash shell.

  • UI de depanare bash

    introduceți descrierea imaginii aici

    Acest debugger bash are caracteristicile complete ale programelor de depanare standard, cum ar fi:

    • Comutarea punctului de rupere
    • Operație pas cu pas unică
    • Funcții și sub-rutine Step-in, Step-out, Step-over
    • Examinarea codului sau a variabilelor în orice moment în timp ce rulează scriptul

    ID-ul Shelled (Shell Script Editor) IDE (Integrated Development Environment) are un bonus suplimentar de a efectua verificarea contextului, evidențierea și indentarea în timp ce scrieți scriptul. Dacă nu este indentată corect, este posibil să puteți imediat să semnalizați / localizați multe erori acolo.

    Apoi există alte beneficii IDE cum ar fi:

    • Lista de activități TODO
    • Activitatea Mylyn
    • Lista de marcaje
    • Mai multe Editarea ferestrelor
    • Partajarea la distanță a mediului

    Comentarii

    • Sfat extraordinar. Îmi pare bine să știu că Bash poate fi depanat astfel.

    Răspuns

    O resursă minunată a apărut în ultimii ani: http://shellcheck.net

    vă arată mai mult decât face bash-ul obișnuit, permițându-vă să găsiți cu ușurință acele ghilimele neplăcute sau închise paranteze etc.

    Asigurați-vă că nu lipiți informații sensibile (ips, parole etc.) pe net … (mai ales că este http, necriptat) (cred că este disponibil și shellcheck pentru a descărca, dar nu sunt sigur)

    Răspunde

    În zilele noastre, există VS Code Bash Debug.

    https://marketplace.visualstudio.com/items?itemName=rogalmic.bash-debug

    Are „Step in / out / peste „și arată, de asemenea, valoarea fiecărei variabile.

    Captură de ecran VS Code Bash Debug

    Comentarii

    • acest răspuns nu abordează întrebarea în contextul potrivit; presupunând linia de comandă deoarece IDE nu a fost menționat

    Răspuns

    pur și simplu utilizați:

    #!/bin/bash -x 

    la fel și pentru shell:

    #!/bin/sh -x 

    Lasă un răspuns

    Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *