Diese geben Ihnen eine Spur von dem, was ausgeführt wird. (Siehe auch "Klarstellung" am Ende der Antwort.)
Manchmal müssen Sie das Debuggen innerhalb des Skripts steuern. In diesem Fall können Sie, wie Cheeto mich erinnerte , Folgendes verwenden:
set-x
Dies aktiviert das Debuggen. Sie können es dann wieder ausschalten mit:
set+x
(Sie können den aktuellen Ablaufverfolgungsstatus ermitteln, indem Sie $-die aktuellen Flags analysieren x.)
Außerdem bieten Shells im Allgemeinen die Optionen ' -n' für 'keine Ausführung' und ' -v' für den 'ausführlichen' Modus. Sie können diese in Kombination verwenden, um festzustellen, ob die Shell glaubt, dass sie Ihr Skript ausführen könnte - gelegentlich nützlich, wenn Sie irgendwo ein unausgeglichenes Zitat haben.
Es besteht die Behauptung, dass sich die -xOption ' ' in Bash von anderen Shells unterscheidet (siehe Kommentare). Das Bash-Handbuch sagt:
-x
Drucken Sie eine Spur einfacher Befehle, forBefehle, caseBefehle, selectBefehle und arithmetischer forBefehle sowie deren Argumente oder zugehöriger Wortlisten, nachdem sie erweitert und ausgeführt wurden. Der Wert der PS4Variablen wird erweitert und der resultierende Wert wird vor dem Befehl und seinen erweiterten Argumenten gedruckt.
Das scheint überhaupt kein anderes Verhalten anzuzeigen. Ich sehe keine anderen relevanten Verweise auf ' -x' im Handbuch. Es werden keine Unterschiede in der Startsequenz beschrieben.
Erläuterung : Auf Systemen wie einer typischen Linux-Box, bei der ' /bin/sh' ein Symlink zu ' /bin/bash' ist (oder wo immer die ausführbare Bash-Datei gefunden wird), erzielen die beiden Befehlszeilen den gleichen Effekt wie das Ausführen des Skripts mit aktivierter Ausführungsablaufverfolgung. Auf anderen Systemen (z. B. Solaris und einigen moderneren Linux-Varianten) /bin/shist Bash nicht vorhanden, und die beiden Befehlszeilen würden (geringfügig) unterschiedliche Ergebnisse liefern. Vor allem /bin/shwürde ' ' durch Konstrukte in Bash verwirrt, die es überhaupt nicht erkennt. (Unter Solaris /bin/shhandelt es sich um eine Bourne-Shell. Unter modernem Linux handelt es sich manchmal um Dash - eine kleinere, strengere POSIX-Shell.) Wenn der Name wie folgt aufgerufen wird, die 'shebang'-Zeile (' #!/bin/bash'vs '#!/bin/sh' '
Das Bash-Handbuch enthält einen Abschnitt zum Bash-POSIX-Modus , der im Gegensatz zu einer langjährigen, aber fehlerhaften Version dieser Antwort (siehe auch die folgenden Kommentare) den Unterschied zwischen "Bash aufgerufen als sh" und "Bash aufgerufen als" ausführlich beschreibt bash'.
Beim Debuggen eines (Bash-) Shell-Skripts ist es sinnvoll und vernünftig - sogar notwendig -, die in der Shebang-Zeile angegebene Shell mit der -xOption zu verwenden. Andernfalls kann (wird?) Beim Debuggen ein anderes Verhalten auftreten als beim Ausführen des Skripts.
Er hat ein bashSkript angegeben. Wenn Sie ein Bash-Skript mit sh -xausführen, verhält es sich völlig anders! Bitte aktualisieren Sie Ihre Antwort.
lhunath
1
@lhunath: Inwiefern bewirkt 'sh -x' (oder 'bash -x'), dass sich ein Skript völlig anders verhält? Offensichtlich gibt es Trace-Informationen an stderr aus; Das ist eine Selbstverständlichkeit (obwohl in meiner Antwort nicht erwähnt). Aber was noch? Ich verwende 'bash' als 'sh' unter Linux und MacOS X und habe kein ernstes Problem bemerkt.
Jonathan Leffler
6
Es gibt Unterschiede beim Start und zur Laufzeit. Sie sind vollständig in der Bash-Distribution dokumentiert.
TheBonsai
4
Hier ist ein Link zum Bash-Dokument: gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files 'Wenn Bash mit dem Namen sh aufgerufen wird, versucht es, das Startverhalten historischer Versionen von sh as nachzuahmen so nah wie möglich, unter Einhaltung des Posix-Standards '
Thethinman
6
Und verwenden Sie die PS4-Eingabeaufforderung, um weitere nützliche Informationen zu geben, wie:export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
estani
28
Ich habe die folgenden Methoden verwendet, um mein Skript zu debuggen.
set -eLässt das Skript sofort anhalten, wenn ein externes Programm einen Exit-Status ungleich Null zurückgibt. Dies ist nützlich, wenn Ihr Skript versucht, alle Fehlerfälle zu behandeln, und wenn ein Fehler aufgetreten ist.
set -x wurde oben erwähnt und ist sicherlich die nützlichste aller Debugging-Methoden.
set -n Dies kann auch nützlich sein, wenn Sie Ihr Skript auf Syntaxfehler überprüfen möchten.
straceist auch nützlich, um zu sehen, was los ist. Besonders nützlich, wenn Sie das Skript nicht selbst geschrieben haben.
Das Stracing eines Skripts (dh das Stracing einer Shell, die das Skript ausführt) ist eine seltsame Shell-Debugging-Methode (kann jedoch bei einer begrenzten Anzahl von Problemen funktionieren).
TheBonsai
1
Ich gebe zu, es ist seltsam und auch sehr ausführlich, aber wenn Sie die Ausgabe von strace auf einige Systemaufrufe beschränken, wird es nützlich.
1
Beachten Sie, dass dies strace -ferforderlich ist, wenn Sie auch Fehler in den vom Skript gestarteten Prozessen finden möchten. (was es um ein Vielfaches ausführlicher macht, aber dennoch nützlich ist, wenn Sie es auf die Syscalls beschränken, an denen Sie interessiert sind).
Ich finde jedoch, dass die "Standard" -Skript-Debugging-Methoden ineffizient, nicht intuitiv und schwer zu verwenden sind. Für diejenigen, die an ausgefeilte GUI-Debugger gewöhnt sind, die alles zur Hand haben und die Arbeit für einfache Probleme zum Kinderspiel machen (und für schwierige Probleme möglich sind), sind diese Lösungen nicht sehr zufriedenstellend.
Ich verwende eine Kombination aus DDD und bashdb. Ersteres führt Letzteres aus, und Letzteres führt Ihr Skript aus. Dies bietet eine Benutzeroberfläche mit mehreren Fenstern die Möglichkeit, Code im Kontext zu durchlaufen und Variablen, Stapel usw. anzuzeigen, ohne die ständige mentale Anstrengung, den Kontext in Ihrem Kopf beizubehalten oder die Quelle immer wieder neu aufzulisten.
Gerade entdeckt ddd dank Ihrer Antwort. In Ubuntu 12.04.3 (64 Bit) funktioniert die Apt-Source-Version nicht. Ich musste aus dem Quellcode kompilieren und installieren, um mit dem Debuggen meines Bash-Skripts zu beginnen. Die Anweisungen hier - askubuntu.com/questions/156906/… haben geholfen.
Chronodekar
Ja, das ist ein Problem. Ich habe es vor einiger Zeit mit einigen Skripten gelöst - 'dddbash' installiert / baut DDD, entfernt die alte Version, wenn sie falsch ist, installiert bashdb usw. (Antwort wurde jetzt mit diesen Informationen bearbeitet)
$ cat test.sh
ARRAY=("hello there" world)for x in $ARRAY;do
echo $x
done
$ shellcheck test.sh
In test.sh line 3:for x in $ARRAY;do^-- SC2128:Expanding an array without an index only gives the first element.
Beheben Sie den Fehler, versuchen Sie es zuerst ...
$ cat test.sh
ARRAY=("hello there" world)for x in ${ARRAY[@]};do
echo $x
done
$ shellcheck test.sh
In test.sh line 3:for x in ${ARRAY[@]};do^-- SC2068:Double quote array expansions, otherwise they're like $* and break on spaces.
Für geschälte: Laden Sie die Zip-Datei herunter und importieren Sie sie über die Hilfe in Eclipse -> Neue Software installieren: Lokales Archiv Für Basheclipse: Kopieren Sie die Gläser in das Dropins-Verzeichnis von Eclipse
Dies ist eine reine Linkantwort (siehe auch hier ). Sie sollten Ihre Antwort erweitern, um hier so viele Informationen wie möglich aufzunehmen, zumindest das Minimum, das erforderlich ist, um das zu erreichen, was Sie vorschlagen, und die Links nur als Referenz verwenden. Grundsätzlich müssen Beiträge zum Stapelüberlauf (und zum gesamten Stapelaustausch) in sich geschlossen sein. Das heißt , dass genügend Informationen Bedürfnisse in Ihrer Antwort sein , so dass der Leser nicht nicht zu brauchen nach dem Weg zu gehen off-site. Im Moment ist das bei dieser Antwort nicht der Fall.
Makyen
Dies ist die erste Antwort, die ich gefunden habe, nachdem ich mir viele angesehen habe, die tatsächlich zeigen, dass echtes Debuggen möglich ist. Die Standardantworten "set + x" stimmen perfekt mit einer in sich geschlossenen Antwort überein, ignorieren jedoch fast absichtlich die wahren Fragen zum echten Debuggen. Ich begrüße diese Antwort 👏
BDB wird derzeit in Englisch und Spanisch unterstützt. Um die Sprache zu ändern, bearbeiten Sie die Datei / etc / default / bdb
abadjm
Der Screenshot sieht interessant aus, aber ich konnte ihn nicht zum Laufen bringen. "bdb.sh: Zeile 32: bdbSTR [1]: ungebundene Variable"; Übrigens werden die aktuellen Werte aller gesetzten Variablen bei jedem Schritt angezeigt, den wir im Code ausführen?
Wassermann Power
2
setze + x = @ECHO AUS, setze -x = @ECHO EIN.
Sie können -xvdem Standard-Shebang die folgende Option hinzufügen :
#!/bin/bash -xv
-x: Zeigt Befehle und ihre Argumente an, während sie ausgeführt werden. -v: Shell-Eingabezeilen beim Lesen anzeigen.
ltraceist ein anderes Linux-Dienstprogramm ähnlich strace. Allerdings ltracelistet alle Bibliotheksaufrufe in einer ausführbaren Datei oder einem laufenden Prozess aufgerufen wird. Sein Name selbst stammt von der Verfolgung von Bibliotheksaufrufen. Beispielsweise:
Der Beitrag enthält Details zum Einführen von Protokollstufen wie INFO, DEBUG, ERROR. Verfolgungsdetails wie Skripteintrag, Skriptexit, Funktionseingang, Funktionsexit.
Antworten:
Diese geben Ihnen eine Spur von dem, was ausgeführt wird. (Siehe auch "Klarstellung" am Ende der Antwort.)
Manchmal müssen Sie das Debuggen innerhalb des Skripts steuern. In diesem Fall können Sie, wie Cheeto mich erinnerte , Folgendes verwenden:
Dies aktiviert das Debuggen. Sie können es dann wieder ausschalten mit:
(Sie können den aktuellen Ablaufverfolgungsstatus ermitteln, indem Sie
$-
die aktuellen Flags analysierenx
.)Außerdem bieten Shells im Allgemeinen die Optionen '
-n
' für 'keine Ausführung' und '-v
' für den 'ausführlichen' Modus. Sie können diese in Kombination verwenden, um festzustellen, ob die Shell glaubt, dass sie Ihr Skript ausführen könnte - gelegentlich nützlich, wenn Sie irgendwo ein unausgeglichenes Zitat haben.Es besteht die Behauptung, dass sich die
-x
Option ' ' in Bash von anderen Shells unterscheidet (siehe Kommentare). Das Bash-Handbuch sagt:-x
Drucken Sie eine Spur einfacher Befehle,
for
Befehle,case
Befehle,select
Befehle und arithmetischerfor
Befehle sowie deren Argumente oder zugehöriger Wortlisten, nachdem sie erweitert und ausgeführt wurden. Der Wert derPS4
Variablen wird erweitert und der resultierende Wert wird vor dem Befehl und seinen erweiterten Argumenten gedruckt.Das scheint überhaupt kein anderes Verhalten anzuzeigen. Ich sehe keine anderen relevanten Verweise auf '
-x
' im Handbuch. Es werden keine Unterschiede in der Startsequenz beschrieben.Erläuterung : Auf Systemen wie einer typischen Linux-Box, bei der '
/bin/sh
' ein Symlink zu '/bin/bash
' ist (oder wo immer die ausführbare Bash-Datei gefunden wird), erzielen die beiden Befehlszeilen den gleichen Effekt wie das Ausführen des Skripts mit aktivierter Ausführungsablaufverfolgung. Auf anderen Systemen (z. B. Solaris und einigen moderneren Linux-Varianten)/bin/sh
ist Bash nicht vorhanden, und die beiden Befehlszeilen würden (geringfügig) unterschiedliche Ergebnisse liefern. Vor allem/bin/sh
würde ' ' durch Konstrukte in Bash verwirrt, die es überhaupt nicht erkennt. (Unter Solaris/bin/sh
handelt es sich um eine Bourne-Shell. Unter modernem Linux handelt es sich manchmal um Dash - eine kleinere, strengere POSIX-Shell.) Wenn der Name wie folgt aufgerufen wird, die 'shebang'-Zeile ('#!/bin/bash
'vs'#!/bin/sh
' 'Das Bash-Handbuch enthält einen Abschnitt zum Bash-POSIX-Modus , der im Gegensatz zu einer langjährigen, aber fehlerhaften Version dieser Antwort (siehe auch die folgenden Kommentare) den Unterschied zwischen "Bash aufgerufen als
sh
" und "Bash aufgerufen als" ausführlich beschreibtbash
'.Beim Debuggen eines (Bash-) Shell-Skripts ist es sinnvoll und vernünftig - sogar notwendig -, die in der Shebang-Zeile angegebene Shell mit der
-x
Option zu verwenden. Andernfalls kann (wird?) Beim Debuggen ein anderes Verhalten auftreten als beim Ausführen des Skripts.quelle
bash
Skript angegeben. Wenn Sie ein Bash-Skript mitsh -x
ausführen, verhält es sich völlig anders! Bitte aktualisieren Sie Ihre Antwort.export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
Ich habe die folgenden Methoden verwendet, um mein Skript zu debuggen.
set -e
Lässt das Skript sofort anhalten, wenn ein externes Programm einen Exit-Status ungleich Null zurückgibt. Dies ist nützlich, wenn Ihr Skript versucht, alle Fehlerfälle zu behandeln, und wenn ein Fehler aufgetreten ist.set -x
wurde oben erwähnt und ist sicherlich die nützlichste aller Debugging-Methoden.set -n
Dies kann auch nützlich sein, wenn Sie Ihr Skript auf Syntaxfehler überprüfen möchten.strace
ist auch nützlich, um zu sehen, was los ist. Besonders nützlich, wenn Sie das Skript nicht selbst geschrieben haben.quelle
strace -f
erforderlich ist, wenn Sie auch Fehler in den vom Skript gestarteten Prozessen finden möchten. (was es um ein Vielfaches ausführlicher macht, aber dennoch nützlich ist, wenn Sie es auf die Syscalls beschränken, an denen Sie interessiert sind).set -e
ist ... kontrovers .Diese Antwort ist gültig und nützlich: https://stackoverflow.com/a/951352
Ich finde jedoch, dass die "Standard" -Skript-Debugging-Methoden ineffizient, nicht intuitiv und schwer zu verwenden sind. Für diejenigen, die an ausgefeilte GUI-Debugger gewöhnt sind, die alles zur Hand haben und die Arbeit für einfache Probleme zum Kinderspiel machen (und für schwierige Probleme möglich sind), sind diese Lösungen nicht sehr zufriedenstellend.
Ich verwende eine Kombination aus DDD und bashdb. Ersteres führt Letzteres aus, und Letzteres führt Ihr Skript aus. Dies bietet eine Benutzeroberfläche mit mehreren Fenstern die Möglichkeit, Code im Kontext zu durchlaufen und Variablen, Stapel usw. anzuzeigen, ohne die ständige mentale Anstrengung, den Kontext in Ihrem Kopf beizubehalten oder die Quelle immer wieder neu aufzulisten.
Hier finden Sie Anleitungen zum Einrichten: http://ubuntuforums.org/showthread.php?t=660223
quelle
Sie können auch "set -x" in das Skript schreiben.
quelle
Ich habe das Shellcheck-Dienstprogramm gefunden und vielleicht finden es einige Leute interessant https://github.com/koalaman/shellcheck
Ein kleines Beispiel:
Beheben Sie den Fehler, versuchen Sie es zuerst ...
Lass es uns erneut versuchen...
jetzt finden!
Es ist nur ein kleines Beispiel.
quelle
Installieren Sie VSCode , fügen Sie dann die Bash-Debug-Erweiterung hinzu, und Sie können im visuellen Modus debuggen. siehe hier in Aktion.
quelle
Verwenden Sie Eclipse mit den Plugins Shelled & Basheclipse.
https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory
Für geschälte: Laden Sie die Zip-Datei herunter und importieren Sie sie über die Hilfe in Eclipse -> Neue Software installieren: Lokales Archiv Für Basheclipse: Kopieren Sie die Gläser in das Dropins-Verzeichnis von Eclipse
Befolgen Sie die Schritte unter https://sourceforge.net/projects/basheclipse/files/?source=navbar
Ich habe ein Tutorial mit vielen Screenshots unter http://dietrichschroff.blogspot.de/2017/07/bash-enabling-eclipse-for-bash.html geschrieben
quelle
Ich habe einen Bash-Debugger gebaut. Probieren Sie es einfach aus. Ich hoffe, es wird https://sourceforge.net/projects/bashdebugingbash helfen
quelle
Sie können
-xv
dem Standard-Shebang die folgende Option hinzufügen :-x
: Zeigt Befehle und ihre Argumente an, während sie ausgeführt werden.-v
: Shell-Eingabezeilen beim Lesen anzeigen.ltrace
ist ein anderes Linux-Dienstprogramm ähnlichstrace
. Allerdingsltrace
listet alle Bibliotheksaufrufe in einer ausführbaren Datei oder einem laufenden Prozess aufgerufen wird. Sein Name selbst stammt von der Verfolgung von Bibliotheksaufrufen. Beispielsweise:Quelle
quelle
Ich denke, Sie können diesen Bash-Debugger ausprobieren: http://bashdb.sourceforge.net/ .
quelle
Ein Trick zum Debuggen Bash Skripte:
Verwenden von
set -[nvx]
Zusätzlich zu
und
zum Stoppen der Müllkippe.
Ich möchte darüber sprechen,
set -v
welcher Dump so klein wie weniger entwickelte Ausgabe ist.Dump-Variablen oder Tracing im laufenden Betrieb
Zum Testen einiger Variablen verwende ich manchmal Folgendes:
zum Hinzufügen:
in Zeile 18 und Ausführen des resultierenden Skripts (mit Argumenten ), ohne sie bearbeiten zu müssen.
Dies könnte natürlich verwendet werden, um Folgendes hinzuzufügen
set [+-][nvx]
:wird
declare -p v1 v2 >&2
nach Zeile 18,set -x
vor Zeile 22 undset +x
vor Zeile 26 hinzugefügt .kleine Probe:
Hinweis: Sorgfalt über
$LINENO
wird durch folgende Faktoren beeinträchtigt werden , on-the-fly Änderungen!(Um das resultierende Skript ohne Ausführung zu sehen, lassen Sie es einfach fallen
bash <(
und) arg1 arg2
)Schritt für Schritt Ausführungszeit
Schauen Sie sich meine Antwort zum Profilieren von Bash-Skripten an
quelle
Es gibt viele Details zur Protokollierung von Shell-Skripten über globale Shell-Variablen. Wir können die ähnliche Art der Protokollierung im Shell-Skript emulieren: http://www.cubicrace.com/2016/03/log-tracing-mechnism-for-shell-scripts.html
Der Beitrag enthält Details zum Einführen von Protokollstufen wie INFO, DEBUG, ERROR. Verfolgungsdetails wie Skripteintrag, Skriptexit, Funktionseingang, Funktionsexit.
Beispielprotokoll:
quelle