Wie debugge ich ein Bash-Skript?

Ich habe einige Probleme mit einigen Skripten in Bash, über Fehler und unerwartete Verhaltensweisen. Ich möchte die Ursachen der Probleme untersuchen, damit ich sie anwenden kann Korrekturen: Gibt es eine Möglichkeit, eine Art „Debug-Modus“ für Bash zu aktivieren, um weitere Informationen zu erhalten?

Antwort

Starten Sie Ihr Bash-Skript mit bash -x ./script.sh oder fügen Sie in Ihrem Skript set -x hinzu, um die Debug-Ausgabe anzuzeigen.


Zusätzlich mit bash 4.1 oder höher:

Wenn Sie die Debug-Ausgabe in eine separate Datei schreiben möchten, fügen Sie diese Ihrem Skript hinzu:

exec 5> debug_output.txt BASH_XTRACEFD="5" 

Siehe: https://stackoverflow.com/a/25593226/3776858


Wenn Sie Zeilennummern sehen möchten, fügen Sie Folgendes hinzu:

PS4="$LINENO: " 


Wenn Sie Zugriff auf Befehl, dann können Sie diesen verwenden, um eine Debug-Ausgabe über Ihr Syslog mit Zeitstempel, Skriptname und Zeilennummer zu schreiben:

#!/bin/bash exec 5> >(logger -t $0) BASH_XTRACEFD="5" PS4="$LINENO: " set -x # Place your code here 

Mit der Option -p des Befehls logger können Sie eine einzelne Einrichtung und Ebene festlegen Die Ausgabe über lokales Syslog in eine eigene Protokolldatei zu schreiben.

Kommentare

  • -v kann ebenfalls hilfreich sein (druckt jede Zeile aus, wenn sie ausgeführt wird. kann mit -x) kombiniert werden. Und siehe auch: bashdb.sourceforge.net
  • Eine weitere wunderbare Ressource ist: Shellcheck .net
  • Was bedeutet “ exec 5 > “ do?
  • @aggsol: Wenn Sie BASH_XTRACEFD="5" verwenden, schreibt bash die Trace-Ausgabe, die generiert wird, wenn set -x ist aktiviert für Dateideskriptor 5. exec 5> >(logger -t $0) leitet die Ausgabe von Dateideskriptor 5 an logger Befehl.
  • Sie fragen sich nur, ob Sie die Zeilennummer und den Pfad oder Namen des Shell-Skripts in PS4 erhalten können?

Antwort

Verwenden von set -x

Ich verwende immer set -x und set +x. Sie können Bereiche umschließen, in denen Sie sehen möchten, was mit ihnen passiert, um die Ausführlichkeit zu erhöhen / zu verringern.

#!/bin/bash set -x ..code to debug... set +x 

log4bash

Auch Wenn Sie Entwicklungsarbeiten durchgeführt haben und mit dem Stil der Logger vertraut sind, die die Namen log4j, log4perl usw. tragen, sollten Sie log4bash .

Auszug

Seien wir ehrlich – einfaches altes Echo schneidet es einfach nicht. log4bash ist ein Versuch, eine bessere Protokollierung für Bash-Skripte zu erreichen (dh die Protokollierung in Bash zu verringern).

Von dort aus können Sie solche Dinge in Ihrem tun Bash-Skripte:

#!/usr/bin/env bash source log4bash.sh log "This is regular log message... log and log_info do the same thing"; log_warning "Luke ... you turned off your targeting computer"; log_info "I have you now!"; log_success "You"re all clear kid, now let"s blow this thing and go home."; log_error "One thing"s for sure, we"re all gonna be a lot thinner."; # If you have figlet installed -- you"ll see some big letters on the screen! log_captains "What was in the captain"s toilet?"; # If you have the "say" command (e.g. on a Mac) log_speak "Resistance is futile"; 

Dies führt zu dieser Art von Ausgabe:

        ss1

log4sh

Wenn Sie etwas Portableres benötigen, gibt es auch das ältere log4sh. Funktioniert ähnlich wie log4bash, hier verfügbar:

Kommentare

  • Unter Ubuntu habe ich alias say="spd-say" in meiner .bashrc, die die say Befehl von anderen Distributionen oder OS X.
  • set -vx wäre eine gute Kombination, wenn es mit Trap-Trap-Read-Debug verwendet wird. Auf diese Weise können Sie Zeile für Zeile und Schritt für Schritt übergehen siehe die Ergebnisse

Antwort

Es gibt einen Bash-Debugger, bashdb , ein installierbares Paket für viele Distributionen. Es verwendet den integrierten erweiterten Debugging-Modus von bash (shopt -s extdebug). Es sieht sehr nach gdb aus; hier ist eine Beispielsitzung, um etwas Geschmack zu verleihen:

$ ls 1st.JPG 2ndJPG.JPG $ cat ../foo.sh for f in *.JPG do newf=${f/JPG/jpg} mv $f $newf done $ bashdb ../foo.sh (foo.sh:1): 1: for f in *.JPG bashdb<0> next (foo.sh:3): 3: newf=${f/JPG/jpg} bashdb<1> next (foo.sh:4): 4: mv $f $newf 

Wie in gdb wird die Anweisung kurz angezeigt, bevor sie ausgeführt werden soll. Wir können also Variablen untersuchen, um zu sehen, was die Anweisung tun wird, bevor sie es tut.

bashdb<2> print $f $newf 1st.JPG 1st.jpg bashdb<3> next (foo.sh:1): 1: for f in *.JPG bashdb<4> next (foo.sh:3): 3: newf=${f/JPG/jpg} bashdb<5> next (foo.sh:4): 4: mv $f $newf bashdb<6> print $f $newf 2ndJPG.JPG 2ndjpg.JPG 

Das ist nicht das, was wir wollen! Schauen wir uns das an Parametererweiterung erneut.

bashdb<7> print $f ${f/JPG/jpg} 2ndJPG.JPG 2ndjpg.JPG bashdb<8> print $f ${f/JPG$/jpg} 2ndJPG.JPG 2ndJPG.JPG bashdb<9> print $f ${f/%JPG/jpg} 2ndJPG.JPG 2ndJPG.jpg 

OK, das funktioniert. Setzen wir newf auf den richtigen Wert.

bashdb<10> eval newf=${f/%JPG/jpg} $? is 0 bashdb<11> print $f $newf 2ndJPG.JPG 2ndJPG.jpg 

Sieht gut aus. Fahren Sie mit dem Skript fort. P. >

bashdb<12> next Debugged program terminated normally. Use q to quit or R to restart. $ ls 1st.jpg 2ndJPG.jpg 

Antwort

Die Standardmethode zum Debuggen von Skripten in den meisten Bourne-basierten Shells, wie z bash schreibt set -x oben in Ihr Skript. Dadurch wird bash ausführlicher darüber, was getan / ausgeführt wird und wie Argumente ausgewertet werden.

-x Print commands and their arguments as they are executed. 

Dies ist entweder für den Interpreter oder für Inside-Skripte nützlich. Zum Beispiel:

$ find "$fileloc" -type f -prune "$filename" -print + find /var/adm/logs/morelogs -type f -prune "-name *.user" -print find: unknown predicate "-name *.user" $ find "$fileloc" -type f -prune $filename -print + find /var/adm/logs/morelogs -type f -prune -name "*.user" -print find: "/var/adm/logs/morelogs": No such file or directory 

Oben sehen wir, warum die Suche aufgrund einiger einfacher Anführungszeichen fehlschlägt.

Um die Funktion zu deaktivieren, geben Sie einfach set +x ein.

Antwort

Verwenden von Eclipse

Sie können die kombinierte Umgebung von Eclipse und Shelled mit dem unten verlinkten Skript „_DEBUG.sh“ verwenden.

Schalen wechseln

By Standardmäßig verwendet das Shelled-Entwicklungstool /bin/dash als Interpreter. Ich habe dies in /bin/bash geändert, um eine bessere Kompatibilität mit den meisten Shell-Beispielen im Web und in meiner Umgebung zu erzielen.

HINWEIS: Sie können dies ändern, indem Sie zu: Fenster -> Präferenz -> Shell-Skript -> Dolmetscher

Installationsanweisungen

Das Debugger-Paket enthält die Schritte zur Verwendung des _DEBUG.sh -Skripts für Ihr Skript-Debugging, das im Grunde (readme.txt) lautet:

  1. Shell-Skriptprojekt erstellen: Datei -> Neu -> Andere – > Shell-Skript

-> Shell-Skriptprojekt-Assistent .

  • Erstellen Sie eine Bash-Skriptdatei: Datei -> Neue -> Datei . In diesem Beispiel ist es script.sh. Die Erweiterung sollte „.sh“ sein und ist ein Muss.
  • Kopieren Sie die Datei _DEBUG.sh in den Projektordner.
  • Fügen Sie die Datei ein folgenden Text am Anfang der Datei script.sh:

    . _DEBUG.sh 
  • Wenn die Datei Wird in Microsoft Windows erstellt, müssen Sie die Datei -> Konvertieren von Zeilenbegrenzern in -> Unix

  • Richten Sie eine Debug-Startkonfiguration ein: Führen Sie aus -> Debug-Konfigurationen -> Bash-Skript … Hier müssen 2 Felder festgelegt werden:

    a) „Bash-Skript:“ – Pfad im Arbeitsbereich von Eclipse zum Bash-Skript zum Debuggen.
    e) „Debugger-Port:“ 33333

  • Wechseln Sie zur Debug-Perspektive. Starten Sie die Debugging-Sitzung. Starten Sie script.sh über die Bash-Shell.

  • Die Bash-Debug-Benutzeroberfläche

    Geben Sie hier die Bildbeschreibung ein.

    Dieser Bash-Debugger bietet alle Funktionen von Standard-Programmier-Debuggern wie:

    • Umschalten des Haltepunkts
    • Einzelne schrittweise Bedienung
    • Step-In-, Step-Out-, Step-Over-Funktionen und Unterprogramme
    • Untersuchen von Code oder Variablen zu jedem Zeitpunkt, während das Skript ausgeführt wird

    Die IDE (Integrated Development Environment) von Shelled (Shell Script Editor) bietet einen zusätzlichen Vorteil beim Durchführen von Kontextprüfungen, Hervorheben und Einrücken beim Schreiben Ihres Skripts. Wenn der Einzug nicht korrekt ist, können Sie möglicherweise sofort viele Fehler dort markieren / lokalisieren.

    Dann gibt es andere IDE-Vorteile wie zum Beispiel:

    • TODO-Aufgabenliste
    • Mylyn-Aufgabe
    • Lesezeichenliste
    • Mehrere Fenster bearbeiten
    • Remote-Freigabe der Umgebung

    Kommentare

    • Cooler Tipp. Schön zu wissen, dass Bash das kann So debuggen Sie.

    Antwort

    In den letzten Jahren ist eine wunderbare Ressource erschienen: http://shellcheck.net

    Es zeigt Ihnen mehr als die normale Bash, sodass Sie diese lästigen, nicht geschlossenen Anführungszeichen oder Locken leicht finden können Klammern usw.

    Stellen Sie nur sicher, dass Sie keine vertraulichen Informationen (IPs, Passwörter usw.) über das Internet einfügen … (insbesondere, da es sich um http, unverschlüsselt handelt) (ich glaube, Shellcheck ist auch verfügbar zum Herunterladen, aber ich bin nicht sicher)

    Antwort

    Heutzutage gibt es das VS Code Bash Debug.

    https://marketplace.visualstudio.com/items?itemName=rogalmic.bash-debug

    Es hat „Step in / out /“ over „und zeigt auch den Wert jeder Variablen an.

    Screenshot des VS Code Bash Debug

    Kommentare

    • Diese Antwort behandelt die Frage nicht im richtigen Kontext. Angenommen, die Befehlszeile wurde nicht erwähnt.

    Antwort

    Verwenden Sie einfach:

    #!/bin/bash -x 

    dasselbe für die Shell:

    #!/bin/sh -x 

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.