Come eseguire il debug di uno script bash?

Ho dei problemi con alcuni script in bash, su errori e comportamenti imprevisti. Vorrei indagare sulle cause dei problemi in modo da poter applicare correzioni. Cè un modo in cui posso attivare una sorta di “modalità di debug” per bash, per ottenere maggiori informazioni?

Risposta

Avvia il tuo script bash con bash -x ./script.sh o aggiungi nel tuo script set -x per vedere loutput di debug.


Aggiuntivo con bash 4.1 o successivo:

Se vuoi scrivere loutput di debug in un file separato, aggiungilo al tuo script:

exec 5> debug_output.txt BASH_XTRACEFD="5" 

Vedi: https://stackoverflow.com/a/25593226/3776858


Se desideri visualizzare i numeri di riga, aggiungi questo:

PS4="$LINENO: " 


Se hai accesso a logger quindi puoi usarlo per scrivere loutput di debug tramite il tuo syslog con timestamp, nome dello script e numero di riga:

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

Puoi utilizzare lopzione -p del comando logger per impostare una singola struttura e livello per scrivere loutput tramite syslog locale nel proprio file di log.

Commenti

  • -v può anche aiutare (stampa ogni riga man mano che vengono eseguite. può essere combinato con -x). E vedi anche: bashdb.sourceforge.net
  • unaltra risorsa meravigliosa è: shellcheck .net
  • Che cosa fa ” exec 5 > ” fare?
  • @aggsol: se utilizzi BASH_XTRACEFD="5" bash scrive loutput di traccia generato quando set -x è abilitato al descrittore di file 5. exec 5> >(logger -t $0) reindirizza loutput dal descrittore di file 5 a logger comando.
  • Mi chiedevo solo se puoi ottenere il numero di riga e il percorso o il nome dello script di shell in PS4?

Risposta

Utilizzo di set -x

Uso sempre set -x e set +x. Puoi raggruppare le aree in cui vuoi vedere cosa sta succedendo con loro per aumentare / diminuire la verbosità.

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

log4bash

Inoltre se hai svolto un lavoro di sviluppo e hai familiarità con lo stile dei logger che si chiamano log4j, log4perl, ecc., potresti utilizzare log4bash .

estratto

Ammettiamolo: il semplice vecchio echo non lo taglia. log4bash è un tentativo di avere una registrazione migliore per gli script Bash (cioè, fare in modo che la registrazione in Bash faccia meno schifo).

Da lì puoi fare cose come questa nel tuo Script 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"; 

risultante in questo tipo di output:

        ss1

log4sh

Se hai bisogno di qualcosa di più portatile, cè anche il vecchio log4sh. Funziona in modo simile a log4bash, disponibile qui:

Commenti

  • Su Ubuntu, ho alias say="spd-say" nel mio .bashrc, che imita il say da altre distribuzioni o OS X.
  • set -vx sarebbe una buona combinazione se usato con trap – trap read debug. Questo ti permette di scorrere riga per riga e vedere i risultati

Risposta

Cè “sa bash debugger, bashdb , che è un pacchetto installabile su molte distribuzioni. Utilizza la modalità di debug estesa incorporata di bash (shopt -s extdebug). Assomiglia molto a gdb; qui “una sessione di esempio per dare un po di sapore:

$ 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 

Come in gdb, listruzione viene mostrata appena prima che sta per essere eseguita. Quindi possiamo esaminare le variabili per vedere cosa farà listruzione prima di farlo.

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 

Non è quello che vogliamo! Guardiamo il di nuovo lespansione dei parametri.

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, funziona. Imposta “s newf sul valore corretto.

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

Sembra buono. Continua lo script.

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

Risposta

Il metodo standard per eseguire il debug degli script nella maggior parte delle shell basate su Bourne, come bash è scrivere set -x allinizio dello script. Ciò renderà bash più dettagliato su ciò che viene fatto / eseguito e su come vengono valutati gli argomenti.

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

questo è utile sia per linterprete che per gli script interni. Ad esempio:

$ 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 

In quanto sopra possiamo vedere perché find non riesce a causa di virgolette singole.

Per disattivare la funzione, digita set +x.

Risposta

Utilizzo di Eclipse

È possibile utilizzare lambiente combinato di Eclipse e Shelled con lo script “_DEBUG.sh” collegato di seguito.

Cambio shell

Di per impostazione predefinita, lo strumento di sviluppo Shelled utilizza /bin/dash come interprete. Ho cambiato questo in /bin/bash per avere una migliore compatibilità con la maggior parte degli esempi di shell sul Web e il mio ambiente.

NOTA: Puoi modificare questa impostazione in: Finestra -> Preferenza -> Shell Script -> Interpreti

Istruzioni per la configurazione

Il pacchetto Debugger contiene i passaggi per utilizzare lo _DEBUG.sh script per il debug dello script che è fondamentalmente (il readme.txt):

  1. Crea progetto script shell: File -> Nuovo -> Altro – > Shell Script

-> Procedura guidata progetto script shell .

  • Crea un file di script Bash: File -> Nuovo -> File . In questo esempio, sarà script.sh. Lestensione deve essere “.sh” ed è un must.
  • Copia il file _DEBUG.sh nella cartella del progetto.
  • Inserisci il testo seguente allinizio del file script.sh:

    . _DEBUG.sh 
  • Se il file viene creato in Microsoft Windows, quindi assicurati di eseguire il File -> Converti delimitatori di riga in -> Unix .

  • Imposta una configurazione di avvio del debug: Esegui -> Configurazioni di debug -> Bash script … Ci sono 2 campi da impostare qui:

    a) “Bash script:” – Percorso nello spazio di lavoro di Eclipse allo script Bash per il debug.
    e) “Porta debugger:” 33333

  • Passa alla prospettiva Debug. Avvia la sessione di debug. Avvia script.sh dalla shell bash.

  • Linterfaccia utente di debug di bash

    inserisci qui la descrizione dellimmagine

    Questo debugger di bash ha tutte le caratteristiche dei debugger di programmazione standard come:

    • Commutazione punto di interruzione
    • Operazione passo passo
    • Step-in, Step-out, Step-over funzioni e sub-routine
    • Esame di codice o variabili in qualsiasi momento durante lesecuzione dello script

    Shelled (Shell Script Editor) IDE (Integrated Development Environment) ha un ulteriore vantaggio di eseguire il controllo del contesto, levidenziazione e lindentazione durante la scrittura dello script. Se non “t rientra correttamente, potresti essere immediatamente in grado di contrassegnare / localizzare molti errori lì.

    Poi ci sono altri vantaggi dellIDE come:

    • Elenco attività TODO
    • Attività Mylyn
    • Elenco segnalibri
    • Più Modifica delle finestre
    • Condivisione remota dellambiente

    Commenti

    • Suggerimento interessante. Bello sapere che Bash può eseguire il debug in questo modo.

    Risposta

    Negli ultimi anni è apparsa una risorsa meravigliosa: http://shellcheck.net

    ti mostra più del normale bash, permettendoti di trovare facilmente quelle fastidiose virgolette non chiuse o ricci parentesi, ecc.

    Assicurati solo di non incollare informazioni sensibili (ips, password, ecc.) sulla rete … (specialmente perchéè http, non criptato) (credo che sia disponibile anche shellcheck da scaricare, ma non ne sono sicuro)

    Risposta

    Al giorno doggi, cè il debug di VS Code Bash.

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

    Ha “Step in / out / over “e mostra anche il valore di ogni variabile.

    Screenshot di debug di VS Code Bash

    Commenti

    • questa risposta non affronta la domanda nel giusto contesto; assumendo la riga di comando poiché IDE non è stato menzionato

    Risposta

    usa semplicemente:

    #!/bin/bash -x 

    lo stesso per la shell:

    #!/bin/sh -x 

    Lascia un commento

    Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *