2012-06-18 11 views
9

Sto cercando un modo per scoprire da quale file e numero di riga è stata chiamata una funzione. La funzione si trova in un file di libreria che viene acquisito dal mio script.Bash: Trova il numero di linea della chiamata di funzione dal file di sourcing

file1:

$source file2 
$warn_me "Error: You didn't do something" 

file2:

$function warn_me() { 
$ message=???? 
$ echo ${message} 
$} 

output desiderato:$: file1: Linea 2: Errore: non hai fatto qualcosa

Il funct la chiamata di ioni già avviene molte volte in molti file, quindi sto cercando di trovare un modo per farlo senza cambiarlo.

In precedenza la funzione warn_me è stato definito in ogni file che ha utilizzato e questo era preso cura di in questo modo:

$local message="$BASH_SOURCE:(""${BASH_LINENO}): ""$*" 

risposta

10

siete alla ricerca di caller sembra.

$ cat h.sh 
#! /bin/bash 
function warn_me() { 
    echo "[email protected]" 
    caller 
} 
$ cat g.sh 
#!/bin/bash 
source h.sh 
warn_me "Error: You didn't do something" 
$ . g.sh 
Error: You didn't do something 
3 g.sh 
+1

Grazie, ho finito per sostituire la linea con: $ messaggio locale = "$ BASH_SOURCE [1] :(" "$ {BASH_LINENO}):" "$ *" – spizzak

6

Ispirato @nosid e @Wrikken ho scritto una piccola funzione per mettere corrente stack trace in una variabile denominata $ STACK. Potrebbe essere utile inviare all'utilizzatore la posizione in cui si è verificato un errore. Peccato che bash non abbia un printStackTrace integrato ... Spero che qualcuno possa trovarlo a portata di mano nei loro progetti.

function get_stack() { 
    STACK="" 
    local i message="${1:-""}" 
    local stack_size=${#FUNCNAME[@]} 
    # to avoid noise we start with 1 to skip the get_stack function 
    for ((i=1; i<$stack_size; i++)); do 
     local func="${FUNCNAME[$i]}" 
     [ x$func = x ] && func=MAIN 
     local linen="${BASH_LINENO[$((i - 1))]}" 
     local src="${BASH_SOURCE[$i]}" 
     [ x"$src" = x ] && src=non_file_source 

     STACK+=$'\n'" at: "$func" "$src" "$linen 
    done 
    STACK="${message}${STACK}" 
} 

Aggiornamento: ho corretto un errore di battitura e aggiunto un parametro di messaggio di errore. Quindi il primo parametro della funzione è un messaggio di errore da aggiungere alla traccia dello stack. btw se il tuo script è fornito sullo stdin bash (una cattiva idea nella maggior parte dei casi), allora la prima posizione andrebbe persa. Se necessario, quindi nel ciclo for, modificarlo in i<$stack_size + 1. Ma come ho detto, non è una buona idea alimentare il tuo script allo stdin di bash, here's why.

Aggiornamento 2: Ho trovato un older answer su questo. Pensato per mantenere meglio la versione aggiornata del codice in un unico posto. Così ho deciso di creare un gist. Sentiti libero di suggerire miglioramenti al succo. Cercherò di mantenere aggiornata questa risposta se si verificano cambiamenti, ma non posso garantire.

Problemi correlati