2012-06-18 14 views
9

Próbuję znaleźć sposób, aby dowiedzieć się, z jakiego pliku i numeru linii została wywołana funkcja. Funkcja znajduje się w pliku biblioteki, który jest pobierany przez mój skrypt.Bash: Znajdź numer wiersza wywołania funkcji z pliku źródłowego

plik1:

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

plik2:

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

Pożądany wyjściowa:$: file1: Linia 2: Błąd: Nie udało zrobić coś

Funkcja Wywołanie jonowe już występuje wiele razy w wielu plikach, więc próbuję znaleźć sposób, aby to zrobić bez zmiany tego.

Wcześniej funkcja warn_me zostało zdefiniowane w każdym pliku, który używany i zostało to załatwione tak:

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

Odpowiedz

10

Szukasz caller się wydaje.

$ 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

Dzięki, skończyło się na wymianie linii z: $ message lokalnej = "$ BASH_SOURCE [1] :(" "$ {BASH_LINENO}): "" $ *" – spizzak

6

Zainspirowany przez @nosid i @ Wrikken napisałem małą funkcję, aby umieścić bieżący ślad stosu w zmiennej o nazwie $ STACK. Przydatne może być podanie użytkownikowi lokalizacji, w której wystąpił błąd. Szkoda, że ​​bash nie ma wbudowanego printStackTrace ... Mam nadzieję, że ktoś może go przydać w swoich projektach.

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}" 
} 

Aktualizacja: Poprawiłem literówkę i dodano parametr komunikatu o błędzie. Tak więc pierwszym parametrem funkcji jest dodanie komunikatu o błędzie do śledzenia stosu. btw jeśli twój skrypt dostarczony na stdin bash (w większości przypadków zły pomysł), to pierwsza pozycja zostanie utracona. Jeśli to konieczne, następnie w pętli for zmień ją na i<$stack_size + 1. Ale jak już powiedziałem, nie jest dobrym pomysłem nakarmienie twojego skryptu bash`s stdin, here's why.

Aktualizacja 2: Znalazłem o tym older answer. Pomyślałem, aby lepiej zachować zaktualizowaną wersję kodu w jednym miejscu. Postanowiliśmy więc zrobić gist. Możesz zasugerować wprowadzenie usprawnień do istoty problemu. Spróbuję zaktualizować tę odpowiedź, jeśli pojawią się jakieś zmiany, ale nie mogę tego zagwarantować.