Come mostrare il numero di riga durante l'esecuzione dello script bash


89

Ho uno script di test che ha molti comandi e genererà molti output, uso set -xo set -ve set -e, quindi lo script si fermerebbe quando si verifica un errore. Tuttavia, è ancora piuttosto difficile per me individuare quale riga ha interrotto l'esecuzione per individuare il problema. Esiste un metodo in grado di visualizzare il numero di riga dello script prima che ogni riga venga eseguita? O visualizzare il numero di riga prima del comando mostra generato da set -x? O qualsiasi metodo in grado di gestire il mio problema di posizione della riga di script sarebbe di grande aiuto. Grazie.

Risposte:


161

Hai detto che stai già usando -x. La variabile PS4indica che il valore è il prompt stampato prima dell'eco della riga di comando quando l' -xopzione è impostata e il valore predefinito è :seguito da uno spazio.

È possibile modificare PS4per emettere il LINENO(Il numero di riga nello script o nella funzione shell attualmente in esecuzione).

Ad esempio, se il tuo script legge:

$ cat script
foo=10
echo ${foo}
echo $((2 + 2))

Eseguendolo così si stamperebbero i numeri di riga:

$ PS4='Line ${LINENO}: ' bash -x script
Line 1: foo=10
Line 2: echo 10
10
Line 3: echo 4
4

http://wiki.bash-hackers.org/scripting/debuggingtips fornisce il massimo PS4che produrrebbe tutto ciò di cui avrai bisogno per il tracciamento:

export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

4
Mi chiedo perché nessuno lo menziona per "Come eseguire il debug degli script di shell?" . Questo è molto meglio del sempliceecho
Suvarna Pattayil

@VusP D'accordo, echoè meglio evitare affermazioni non necessarie .
devnull

2
Non posso fare a meno di pensare che -x dovrebbe stampare i numeri di riga. O, forse, nx dovrebbe includere i numeri di riga. Per me, è uno di quei momenti "WTF" ...
jww

1
Amico, vorrei sapere prima di quella miscela per PS4 ... Mi avrebbe risparmiato così tanti mal di testa
niken

2
\033[0;33m+(${BASH_SOURCE}:${LINENO}):\033[0m ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'per alcuni colori
Ulysse BN

35

In Bash, $LINENOcontiene il numero di riga in cui lo script è attualmente in esecuzione.

Se hai bisogno di conoscere il numero di riga in cui è stata chiamata la funzione, prova $BASH_LINENO. Nota che questa variabile è un array.

Per esempio:

#!/bin/bash       

function log() {
    echo "LINENO: ${LINENO}"
    echo "BASH_LINENO: ${BASH_LINENO[*]}"
}

function foo() {
    log "$@"
}

foo "$@"

Vedi qui per i dettagli delle variabili Bash.


0

Soluzione semplice (ma potente): posiziona echoil codice che ritieni sia la causa del problema e sposta echoriga per riga finché i messaggi non vengono più visualizzati sullo schermo, perché lo script si è interrotto a causa di un errore prima.

Soluzione ancora più potente: installa bashdbil debugger bash ed esegui il debug dello script riga per riga


2
echoIn molti casi può essere d'aiuto, ma non è sufficiente quando si tenta di applicarlo a funzioni che hanno un output significativo e analizzabile.
Eliran Malka

1
@EliranMalka Punto giusto. In questo caso puoi fare l'eco a stderr:echo "foo" >&2
hek2mgl

1
... si dovrebbe fare eco a stderr in tutti i casi in cui lo scopo sono messaggi di natura diagnostica.
Charles Duffy

0

Soluzione alternativa per i gusci senza LINENO

In uno script abbastanza sofisticato non vorrei vedere tutti i numeri di riga; piuttosto vorrei avere il controllo dell'output.

Definisci una funzione

echo_line_no () {
    grep -n "$1" $0 |  sed "s/echo_line_no//" 
    # grep the line(s) containing input $1 with line numbers
    # replace the function name with nothing 
} # echo_line_no

Usalo con virgolette come

echo_line_no "this is a simple comment with a line number"

L'output è

16   "this is a simple comment with a line number"

se il numero di questa riga nel file sorgente è 16.

Questo fondamentalmente risponde alla domanda Come mostrare il numero di riga durante l'esecuzione dello script bash per gli utenti di ash o altre shell senza LINENO.

Qualcos'altro da aggiungere?

Sicuro. Perchè ti serve? Come lavori con questo? Cosa puoi fare con questo? Questo semplice approccio è davvero sufficiente o utile? Perché vuoi armeggiare con questo?

Voglio sapere di più? Leggi le riflessioni sul debug

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.