Come eseguire il debug di uno script bash?

C’è un modo per eseguire il debug di uno script bash? E. g qualcosa che stampa una sorta di log di esecuzione come “chiamata ” 1″, “chiamando la linea 2” etc.

InformationsquelleAutor corvus | 2009-06-04



12 Replies
  1. 184
    sh -x script [arg1 ...]
    bash -x script [arg1 ...]

    Questi vi darà una traccia di ciò che è stato eseguito. (Vedi anche ‘Chiarimento’ in fondo alla risposta).

    A volte, è necessario controllare il debug di script. In questo caso, come Cheeto ricordato me, è possibile utilizzare:

    set -x

    Questo attiva il debug. È quindi possibile disattivarlo di nuovo con:

    set +x

    (Potete trovare la corrente lo stato della traccia analizzando $-, l’attuale bandiere, per x.)

    Anche, conchiglie, in genere, offrono opzioni di ‘-n‘ per ‘no di esecuzione’ e ‘-v‘ per ‘verbose’ modalità; è possibile utilizzare questi in combinazione per vedere se il guscio si ritiene che potrebbe eseguire il tuo script — di tanto in tanto utile se si dispone di uno squilibrio citazione da qualche parte.


    C’è da dimostrare che i ‘-x‘ opzione in Bash è diverso da altre conchiglie (vedi i commenti). Il Manuale Bash dice:

    • -x

      Stampa una traccia di semplici comandi, for comandi, case comandi, select comandi, e l’aritmetica for comandi e i loro argomenti o parole associate liste dopo aver espanso e prima dell’esecuzione. Il valore della PS4 variabile è espansa e il valore risultante viene stampato prima il comando e i suoi argomenti espansi.

    Che molto non sembrano indicare un comportamento differente a tutti. Non vedo altri pertinenti riferimenti alla ‘-x‘ nel manuale. Non descrivere le differenze nella sequenza di avvio.

    Chiarimento: Su sistemi come un tipico Linux box, dove ‘/bin/sh‘ è un collegamento simbolico a ‘/bin/bash‘ (o dove il Bash eseguibile si trova), le due righe di comando per ottenere l’effetto equivalente di eseguire lo script con l’esecuzione di traccia. Su altri sistemi (per esempio, Solaris, e alcune più moderne varianti di Linux), /bin/sh non è Bash, e le due righe di comando darebbe (leggermente) diversi risultati. Più in particolare, ‘/bin/sh‘ potrebbe essere confuso da costrutti in Bash che non riconosce a tutti. (Su Solaris, /bin/sh è una shell Bourne; su Linux moderni, a volte è Dash — un più piccolo, più strettamente POSIX-solo shell). Quando è chiamato per nome come questo, il “shebang” linea (‘#!/bin/bash‘ vs '#!/bin/sh‘) all’inizio del file non ha alcun effetto sul modo in cui i contenuti vengono interpretati.

    Il manuale Bash ha una sezione su Bash modalità POSIX che, al contrario di una lunga ma errata versione di questa risposta (vedi anche i commenti qui sotto), è descritto in un ampio dettaglio la differenza tra ‘Bash invocato come sh‘ e ‘Bash invocato come bash‘.

    Durante il debug di un (Bash) script di shell, sarà sensibile e sane, è necessario anche — per usare la shell chiamato in shebang linea con il -x opzione. In caso contrario, si può (o si?) ottenere diversi comportamenti durante il debug da quando l’esecuzione dello script.

    • Ha fatto specificare un bash script. E l’esecuzione di uno script bash con sh -x causerà un comportamento completamente diverso! Si prega di aggiornare la tua risposta.
    • In che modo la ‘sh -x’ (o ‘bash -x’) creare uno script si comportano in modo completamente diverso? Ovviamente, uscite di informazioni di traccia stderr; che è un dato di fatto (anche se non indicato nella mia risposta). Ma cos’altro? Io uso ‘bash’ come ‘sh’ su Linux e MacOS X e non ho notato un problema serio.
    • Ci sono differenze, in avvio e in fase di runtime. Sono completamente documentati nella Bash di distribuzione.
    • Lasciatemi chiarire: l’Esecuzione di un bash script con sh cause interprete per disattivare (quasi) tutti bash-caratteristiche, lasciando solo il POSIX quelli. Dato che OP ha detto che il suo script è uno script bash, non deve essere eseguito con sh. Se lo è, masse di errori seguire, inaspettato e, a seconda dello script, davvero brutta roba potrebbe accadere, come i file eliminato e così via.
    • Ecco un link per la bash doc: gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files ‘Se Bash è chiamata con il nome di sh, tenta di imitare il comportamento di avvio delle vecchie versioni di sh come strettamente possibile, pur rispettando lo standard posix e’
    • E uso la PS4 prompt di dare informazioni più utili come: export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
    • “Su sistemi come un tipico Linux box, dove ‘/bin/sh’ è un collegamento simbolico a/bin/bash'” Nota: Su ubuntu /bin/sh è dash, non bash. vedere wiki.ubuntu.com/DashAsBinSh
    • quindi Ubuntu non è un tipico Linux box, o quello che era tipico nel 2010 non è più tipica nel 2014. O entrambi…

  2. 27

    Sono stati utilizzati i seguenti metodi per eseguire il debug di script.

    set -e rende lo script interrompere immediatamente se uno qualsiasi programma esterno restituisce un valore non-zero lo stato di uscita. Questo è utile se il tuo script tenta di gestire tutti i casi di errore e di cui mancata dovrebbe essere intrappolati.

    set -x è stato menzionato sopra ed è sicuramente il più utile di tutti i metodi di debug.

    set -n potrebbe anche essere utile se si desidera controllare il vostro script per gli errori di sintassi.

    strace è utile anche per vedere cosa sta succedendo. Particolarmente utile se non hai scritto lo script manualmente.

    • Stracing uno script (cioè stracing una shell in esecuzione lo script) è un strano shell di debug metodo (ma può funzionare per un numero limitato di problemi).
    • Ammetto che è strano e anche molto dettagliato, ma se si limita l’output di strace per un paio di chiamate di sistema, diventa utile.
    • Nota che strace -f è necessario se si desidera trovare errori nei processi avviati da script. (il che rende molte volte più dettagliato, ma ancora utile se si limite per le chiamate di sistema di cui sei interessato).
    • set -e è… controvercial.
  3. 12

    Questa risposta è valida e utile: https://stackoverflow.com/a/951352

    Ma trovo che lo “standard” debug degli script metodi sono inefficaci, istintivo, e difficile da usare. Per chi è abituato a sofisticati debugger GUI che messo tutto a portata di mano e rendere il lavoro un gioco da ragazzi per problemi facili (e possibile per problemi difficili), queste soluzioni non sono molto soddisfacenti.

    Quello che faccio è usare una combinazione di DDD e bashdb. L’ex esegue questi ultimi, e gli ultimi che esegue lo script. Questo fornisce un multi-finestra di interfaccia utente con la possibilità di passaggio attraverso il codice nel contesto e visualizzare le variabili, stack, ecc…. senza il costante sforzo mentale per mantenere il contesto in testa o continuare a ri-elencare la fonte.

    C’è una guida su l’impostazione che qui: http://ubuntuforums.org/showthread.php?t=660223

    • Appena scoperto ddd grazie per la tua risposta. In Ubuntu 12.04.3 (64bit), l’apt-sources versione non funziona. Ho dovuto compilare & installare da sorgente per avviare il debug di script bash. Le istruzioni qui – askubuntu.com/questions/156906/… aiutato.
    • Sì, è un problema. Ho risolto un po ‘ di tempo di nuovo con qualche script — ‘dddbash” installa/costruisce DDD, rimuove la vecchia versione se il suo male, installa bashdb, etc. (Risposta è stata modificata con questa info ora)
  4. 9

    Si può anche scrivere “set-x” all’interno dello script.

    • E si può scrivere “set +x” per disattivarlo.
  5. 8

    Ho trovato shellcheck utilità e può essere che alcune persone trovano interessante
    https://github.com/koalaman/shellcheck

    Un piccolo esempio:

    $ cat test.sh 
    ARRAY=("hello there" world)
    
    for x in $ARRAY; do
      echo $x
    done
    
    $ shellcheck test.sh 
    
    In test.sh line 3:
    for x in $ARRAY; do
             ^-- SC2128: Expanding an array without an index only gives the first element.

    risolvere il bug, primo tentativo…

    $ cat test.sh       
    ARRAY=("hello there" world)
    
    for x in ${ARRAY[@]}; do
      echo $x
    done
    
    $ shellcheck test.sh
    
    In test.sh line 3:
    for x in ${ARRAY[@]}; do
             ^-- SC2068: Double quote array expansions, otherwise they're like $* and break on spaces.

    Proviamo di nuovo…

    $ cat test.sh 
    ARRAY=("hello there" world)
    
    for x in "${ARRAY[@]}"; do
      echo $x
    done
    
    $ shellcheck test.sh

    trovare ora!

    È solo un piccolo esempio.

    • E ‘ online!
    • Fortunatamente lo strumento si è evoluta al punto in cui si trova anche il restante bug.
  6. 3

    Installare VSCode, quindi aggiungere bash estensione debug e si è pronti per eseguire il debug in modalità visuale. vedere Qui in azione.

    Come eseguire il debug di uno script bash?

  7. 2

    Ho costruito un Bash debugger. Basta dare una prova. Spero che sarà di aiuto
    https://sourceforge.net/projects/bashdebugingbash

    • BDB è attualmente supportato in lingua inglese e spagnola. Per cambiare la lingua, modificare il file /etc/default/bdb
    • la schermata si presenta interessante, ma non ho potuto farlo funzionare “bdb.sh: linea 32: bdbSTR[1]: unbound variabile”; btw mostrerà i valori attuali di tutti impostare le variabili di ogni passo che facciamo sul codice?
  8. 2

    set +x = @ECHO OFF set-x = @ECHO.


    È possibile aggiungere -xv opzione per la norma Inserita come segue:

    #!/bin/bash -xv  

    -x : Visualizzare i comandi e i loro argomenti, in quanto sono eseguite.

    -v : Display shell linee di ingresso in quanto sono leggere.


    ltrace è un altro Linux Utilità simile a strace. Tuttavia, ltrace elenca tutte le chiamate di libreria in un file eseguibile o un processo in esecuzione. Il suo stesso nome deriva dalla biblioteca-chiamare analisi. Per esempio:

    ltrace ./executable <parameters>  
    ltrace -p <PID>  

    Fonte

  9. 1

    Uso eclipse con il plugin sgusciate & basheclipse.

    https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory

    Per sgusciate: Scaricare il file zip ed importare in eclipse tramite help -> installa un nuovo software : archivio locale Per basheclipse: Copia i vasetti in dropins directory di eclipse

    Seguire la procedura fornisce https://sourceforge.net/projects/basheclipse/files/?source=navbar

    Come eseguire il debug di uno script bash?

    Ho scritto un tutorial con molti screenshot a http://dietrichschroff.blogspot.de/2017/07/bash-enabling-eclipse-for-bash.html

    • Questo è un caso limite di link-unica risposta (vedi anche qui). Si dovrebbe espandere la tua risposta per includere più informazioni qui possibile, almeno il minimo necessario per realizzare effettivamente quello che lei suggerisce, e utilizzare il link solo per riferimento. In sostanza, i post su Stack Overflow (e tutti di Stack Exchange) deve essere autonomo. Che significa abbastanza informazione deve essere nella tua risposta in modo tale che il lettore non necessario andare off-site per le indicazioni. Proprio ora, che non è il caso per questa risposta.
    • questa è la prima risposta che ho trovato dopo aver guardato molti che in realtà mostra che la vera debug è possibile. La risposta standard “set +x” corrisponde perfettamente a sé conteneva risposta, ma quasi volontariamente ignorare le vere domande sul vera di debug. Non posso che applaudire questa risposta 👏
  10. 0

    Qualche trucco per eseguire il debug script:

    Utilizzando set -[nvx]

    Oltre a

    set -x

    e

    set +x

    per fermare la discarica.

    Vorrei parlare di set -v che il dump, più piccole, meno sviluppato di uscita.

    bash <<<$'set -x\nfor i in {0..9};do\n\techo $i\n\tdone\nset +x' 2>&1 >/dev/null|wc -l
    21
    
    for arg in x v n nx nv nvx;do echo "- opts: $arg"
        bash 2> >(wc -l|sed s/^/stderr:/) > >(wc -l|sed s/^/stdout:/) <<eof
            set -$arg
            for i in {0..9};do
                echo $i
              done
            set +$arg
            echo Done.
    eof
        sleep .02
      done
    - opts: x
    stdout:11
    stderr:21
    - opts: v
    stdout:11
    stderr:4
    - opts: n
    stdout:0
    stderr:0
    - opts: nx
    stdout:0
    stderr:0
    - opts: nv
    stdout:0
    stderr:5
    - opts: nvx
    stdout:0
    stderr:5

    Dump variabili o l’analisi al volo

    Per il test di alcune variabili, io uso a volte questo:

    bash <(sed '18ideclare >&2 -p var1 var2' myscript.sh) args

    per l’aggiunta di:

    declare >&2 -p var1 var2

    alla riga 18 e l’esecuzione di script risultante (con args), senza dover modificare.

    naturalmente, questo potrebbe essere usato per aggiungere set [+-][nvx]:

    bash <(sed '18s/$/\ndeclare -p v1 v2 >\&2/;22s/^/set -x\n/;26s/^/set +x\n/' myscript) args

    aggiungere declare -p v1 v2 >&2 dopo la riga 18, set -x prima linea 22 e set +x prima linea 26.

    piccolo esempio:

    bash <(sed '2,3s/$/\ndeclare -p LINENO i v2 >\&2/;5s/^/set -x\n/;7s/^/set +x\n/' <(
            seq -f 'echo [email protected], $((i=%g))' 1 8)) arg1 arg2
    arg1 arg2, 1
    arg1 arg2, 2
    declare -i LINENO="3"
    declare -- i="2"
    /dev/fd/63: line 3: declare: v2: not found
    arg1 arg2, 3
    declare -i LINENO="5"
    declare -- i="3"
    /dev/fd/63: line 5: declare: v2: not found
    arg1 arg2, 4
    + echo arg1 arg2, 5
    arg1 arg2, 5
    + echo arg1 arg2, 6
    arg1 arg2, 6
    + set +x
    arg1 arg2, 7
    arg1 arg2, 8

    Nota: Cura circa $LINENO sarà interessato da on-the-fly modifiche!

    ( Per vedere script risultante senza l’esecuzione, è sufficiente trascinare bash <( e ) arg1 arg2 )

    Passo passo, il tempo di esecuzione del

    Guardare la mia risposta su come profilo script bash

  11. 0

    C’è una buona quantità di dettagli sulla registrazione, per gli script di shell, via globale varaibles di shell. Siamo in grado di emulare il simile tipo di registrazione in script di shell: http://www.cubicrace.com/2016/03/log-tracing-mechnism-for-shell-scripts.html

    Il post continua introdducing livelli di log come INFORMAZIONI di DEBUG , di ERRORE.
    Dati di analisi come la voce di script, script di uscita, di ingresso della funzione, la funzione di uscita.

    Registro di esempio:

    Come eseguire il debug di uno script bash?

Lascia un commento