webentwicklung-frage-antwort-db.com.de

Wie wird die Zeilennummer beim Ausführen des Bash-Skripts angezeigt

Ich habe ein Testskript, das viele Befehle enthält und viele Ausgaben erzeugen wird. Ich verwende set -x oder set -v und set -e, sodass das Skript angehalten wird, wenn ein Fehler auftritt. Es ist jedoch immer noch ziemlich schwierig für mich zu finden, welche Zeile die Ausführung gestoppt hat, um das Problem zu lokalisieren. Gibt es eine Methode, mit der die Zeilennummer des Skripts ausgegeben werden kann, bevor jede Zeile ausgeführt wird? Die Zeilennummer vor der Befehlsausstellung, die von set -x? .__ generiert wurde, oder eine Methode, die sich mit dem Problem mit der Skriptzeile befassen kann, wäre eine große Hilfe. Vielen Dank.

58
dspjm

Sie erwähnen, dass Sie -x bereits verwenden. Die Variable PS4 gibt an, dass der Wert die Eingabeaufforderung ist, die ausgegeben wird, bevor die Befehlszeile wiederholt wird, wenn die -x-Option festgelegt ist. Der Standardwert ist :, gefolgt von Leerzeichen.

Sie können PS4 ändern, um die LINENO auszugeben (die Zeilennummer im Skript oder die Shell-Funktion, die gerade ausgeführt wird).

Wenn Ihr Skript beispielsweise lautet:

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

Die Ausführung würde also Zeilennummern drucken:

$ 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 gibt den ultimativen PS4 aus, der alles ausgeben würde, was Sie möglicherweise zur Rückverfolgung benötigen:

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

In Bash enthält $LINENO die Zeilennummer, in der das Skript gerade ausgeführt wird.

Wenn Sie die Zeilennummer kennen müssen, in der die Funktion aufgerufen wurde, versuchen Sie $BASH_LINENO. Beachten Sie, dass diese Variable ein Array ist.

Zum Beispiel:

#!/bin/bash       

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

function foo() {
    log "[email protected]"
}

foo "[email protected]"

Siehe hier für Details zu Bash-Variablen.

21
Deqing

Workaround für Muscheln ohne LINENO

In einem ziemlich raffinierten Skript möchte ich nicht alle Zeilennummern sehen; Ich möchte lieber die Ausgabe kontrollieren. 

Funktion definieren

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

Verwenden Sie es mit Anführungszeichen wie 

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

Ausgabe ist

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

wenn die Nummer dieser Zeile in der Quelldatei 16 ist. 

Dies beantwortet im Wesentlichen die Frage Wie wird die Zeilennummer beim Ausführen des Bash-Skripts angezeigt für Benutzer von Ash oder anderen Shells ohne LINENO

Noch etwas hinzuzufügen? 

Sicher. Warum brauchst du das? Wie arbeitest du damit? Was kannst du damit machen? Ist dieser einfache Ansatz wirklich ausreichend oder nützlich? Warum willst du überhaupt daran basteln?

Möchten Sie mehr wissen? Lesen Sie die Überlegungen zum Debuggen

0
kklepper

Einfache (aber leistungsfähige) Lösung: Platzieren Sie echo um den Code, von dem Sie denken, dass er das Problem verursacht, und verschieben Sie echo Zeile für Zeile, bis die Meldungen nicht mehr auf dem Bildschirm angezeigt werden - weil das Skript aufgrund eines Fehlers angehalten hat.

Noch leistungsfähigere Lösung: Installieren Sie bashdb den bash-Debugger und debuggen Sie das Skript Zeile für Zeile

0
hek2mgl