Mam skrypt testowy, który ma wiele poleceń i generuje dużo danych wyjściowych, używam set -x
lub set -v
i set -e
, więc skrypt zatrzymywał się, gdy wystąpił błąd. Jednak nadal jest mi dość trudno zlokalizować, która linia spowodowała zatrzymanie wykonywania w celu zlokalizowania problemu. Czy istnieje metoda, która może wyświetlić numer wiersza skryptu przed wykonaniem każdego wiersza? Lub wyprowadzić numer wiersza przed wyświetleniem poleceń wygenerowanym przez set -x
? Lub każda metoda, która może rozwiązać mój problem z lokalizacją linii skryptu, byłaby bardzo pomocna. Dzięki.
89
echo
echo
najlepiej unikać niepotrzebnych wypowiedzi.-x
powinno to wypisać numery wierszy. A może -nx
powinien zawierać numery linii. Dla mnie to jeden z tych „WTF” momentów ...\033[0;33m+(${BASH_SOURCE}:${LINENO}):\033[0m ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
dla niektórych kolorówW Bash
$LINENO
zawiera numer wiersza, w którym skrypt jest obecnie wykonywany.Jeśli chcesz znać numer wiersza, w którym funkcja została wywołana, spróbuj
$BASH_LINENO
. Zauważ, że ta zmienna jest tablicą.Na przykład:
#!/bin/bash function log() { echo "LINENO: ${LINENO}" echo "BASH_LINENO: ${BASH_LINENO[*]}" } function foo() { log "$@" } foo "$@"
Zobacz tutaj, aby uzyskać szczegółowe informacje na temat zmiennych Bash.
źródło
Proste (ale wydajne) rozwiązanie: Umieść
echo
wokół kodu, który Twoim zdaniem powoduje problem i przesuwajecho
wiersz po wierszu, aż komunikaty nie pojawią się już na ekranie - ponieważ skrypt zatrzymał się z powodu wcześniejszego błędu.Jeszcze potężniejsze rozwiązanie: zainstaluj
bashdb
debuger bash i debuguj skrypt wiersz po wierszuźródło
echo
w wielu przypadkach może pomóc, ale nie wystarczy, gdy spróbujesz zastosować je w funkcjach, które mają sensowne, analizowalne wyniki.echo "foo" >&2
Obejście problemu dla muszli bez LINENO
W dość wyrafinowanym skrypcie nie chciałbym widzieć wszystkich numerów linii; raczej chciałbym mieć kontrolę nad produkcją.
Zdefiniuj funkcję
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
Użyj go z cudzysłowami, takimi jak
echo_line_no "this is a simple comment with a line number"
Wyjście jest
16 "this is a simple comment with a line number"
jeśli numer tej linii w pliku źródłowym wynosi 16.
To w zasadzie odpowiada na pytanie, jak wyświetlić numer linii podczas wykonywania skryptu bash dla użytkowników ash lub innych powłok bez
LINENO
.Coś więcej do dodania?
Pewnie. Dlaczego tego potrzebujesz? Jak z tym pracujesz? Co możesz z tym zrobić? Czy to proste podejście jest naprawdę wystarczające lub przydatne? Dlaczego w ogóle chcesz przy tym majstrować?
Chcieć wiedzieć więcej? Przeczytaj uwagi na temat debugowania
źródło