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
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:
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 ilsay
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.
- Plug-in con shell di Eclipse:
http://sourceforge.net/projects/shelled/files/shelled/update/ - debugger bash – funziona solo con shelled:
http://sourceforge.net/projects/basheclipse/
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):
- Crea progetto script shell: File -> Nuovo -> Altro – > Shell Script
-> Procedura guidata progetto script shell .
script.sh
. Lestensione deve essere “.sh” ed è un must. _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
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.
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
BASH_XTRACEFD="5"
bash scrive loutput di traccia generato quandoset -x
è abilitato al descrittore di file 5.exec 5> >(logger -t $0)
reindirizza loutput dal descrittore di file 5 alogger
comando.