Wenn ich ein langes R-Skript über die Befehlszeile ausführe (R --slave script.R), wie kann ich es dazu bringen, bei Fehlern Zeilennummern anzugeben?
Ich möchte dem Skript keine Debug-Befehle hinzufügen, wenn dies überhaupt möglich ist. Ich möchte nur, dass sich R wie die meisten anderen Skriptsprachen verhält.
Antworten:
Dies gibt Ihnen nicht die Zeilennummer, sondern zeigt Ihnen, wo der Fehler im Aufrufstapel auftritt, was sehr hilfreich ist:
[Bearbeiten:] Wenn Sie ein Skript über die Befehlszeile ausführen, müssen Sie ein oder zwei Aufrufe überspringen. Siehe traceback () für interaktive und nicht interaktive R-Sitzungen
Mir ist kein anderer Weg bekannt, dies ohne die üblichen Debugging-Verdächtigen zu tun:
Vielleicht möchten Sie sich diesen verwandten Beitrag ansehen.
[Bearbeiten:] Entschuldigung ... habe gerade gesehen, dass Sie dies über die Befehlszeile ausführen. In diesem Fall würde ich vorschlagen, mit den Optionen (Fehler) zu arbeiten. Hier ist ein einfaches Beispiel:
Sie können ein Skript unter einer Fehlerbedingung so ausführlich erstellen, wie Sie möchten. Sie sollten also nur entscheiden, welche Informationen Sie zum Debuggen benötigen.
Wenn Sie bestimmte Bereiche betreffen (z. B. eine Verbindung zu einer Datenbank herstellen), schließen Sie diese in eine tryCatch () - Funktion ein.
quelle
options(error=function() { traceback(2); if(!interactive()) quit("no", status = 1, runLast = FALSE) })
(siehe Kommentar der akzeptierten Antwort). Ich denke, es wäre sinnvoll, es der Antwort hier hinzuzufügen, anstatt nur einen Link zu einem anderen Thread bereitzustellen.Wenn Sie dies tun, erhalten Sie
options(error=traceback)
etwas mehr Informationen über den Inhalt der Zeilen, die zum Fehler geführt haben. Bei einem Fehler wird ein Traceback angezeigt. Bei einigen Fehlern wird die Zeilennummer vorangestellt#
. Aber es ist ein Hit oder Miss, viele Fehler erhalten keine Zeilennummern.quelle
No traceback available
nach dem Fehler.Unterstützung dafür wird in R 2.10 und höher bereitgestellt. Duncan Murdoch hat gerade am 10. September 2009 bei r-devel über findLineNum und setBreapoint gepostet :
quelle
Sie tun es durch Einstellen
Ich frage mich nur, warum diese Einstellung in R keine Standardeinstellung ist. Es sollte so sein, wie es in jeder anderen Sprache ist.
quelle
Die Angabe der globalen R-Option für die Behandlung nicht katastrophaler Fehler hat bei mir funktioniert, zusammen mit einem angepassten Workflow zum Speichern von Informationen über den Fehler und zum Überprüfen dieser Informationen nach dem Fehler. Ich verwende derzeit R Version 3.4.1. Im Folgenden habe ich eine Beschreibung des für mich funktionierenden Workflows sowie einen Code eingefügt, mit dem ich die globale Fehlerbehandlungsoption in R festgelegt habe.
Wie ich es konfiguriert habe, erstellt die Fehlerbehandlung auch eine RData-Datei, die alle Objekte im Arbeitsspeicher zum Zeitpunkt des Fehlers enthält. Dieser Speicherauszug kann mithilfe von R zurückgelesen werden,
load()
und dann können die verschiedenen Umgebungen, wie sie zum Zeitpunkt des Fehlers vorhanden waren, mithilfe interaktiv überprüft werdendebugger(errorDump)
.Ich werde bemerken, dass ich in der
traceback()
Ausgabe Zeilennummern von allen benutzerdefinierten Funktionen innerhalb des Stapels erhalten konnte, aber nur, wenn ich diekeep.source=TRUE
Option beim Aufrufensource()
von benutzerdefinierten Funktionen verwendet habe, die in meinem Skript verwendet wurden. Ohne diese Option wurde durch Festlegen der globalen Fehlerbehandlungsoption wie unten die vollständige Ausgabe vontraceback()
an ein Fehlerprotokoll mit dem Namen gesendeterror.log
, aber die Zeilennummern waren nicht verfügbar.Hier sind die allgemeinen Schritte, die ich in meinem Workflow unternommen habe, und wie ich nach einem nicht interaktiven R-Fehler auf den Speicherauszug und das Fehlerprotokoll zugreifen konnte.
Ich habe Folgendes oben in das Hauptskript eingefügt, das ich über die Befehlszeile aufgerufen habe. Dies legt die globale Fehlerbehandlungsoption für die R-Sitzung fest. Mein Hauptskript wurde aufgerufen
myMainScript.R
. Die verschiedenen Zeilen im Code enthalten Kommentare, die beschreiben, was sie tun. Grundsätzlich wird mit dieser Option, wenn R auf einenstop()
auslösenden Fehler stößt , eine RData (* .rda) -Dump-Datei des Arbeitsspeichers in allen aktiven Umgebungen im Verzeichnis erstellt~/myUsername/directoryForDump
und ein Fehlerprotokollerror.log
mit einigen nützlichen Informationen in das Verzeichnis geschrieben gleiches Verzeichnis. Sie können dieses Snippet ändern, um eine andere Fehlerbehandlung hinzuzufügen (z. B. einen Zeitstempel zur Speicherauszugsdatei und zu den Dateinamen des Fehlerprotokolls usw. hinzufügen).Stellen Sie sicher, dass aus dem Hauptskript und allen nachfolgenden Funktionsaufrufen die Option
keep.source=TRUE
verwendet wird , wenn eine Funktion bezogen wird. Das heißt, um eine Funktion zu beschaffen, würden Sie verwendensource('~/path/to/myFunction.R', keep.source=TRUE)
. Dies ist erforderlich, damit dietraceback()
Ausgabe Zeilennummern enthält. Es sieht so aus, als könnten Sie diese Option möglicherweise auch global festlegenoptions( keep.source=TRUE )
, aber ich habe dies nicht getestet, um festzustellen, ob es funktioniert. Wenn Sie keine Zeilennummern benötigen, können Sie diese Option weglassen.Rscript myMainScript.R
. Dadurch wird eine neue nicht interaktive R-Sitzung gestartet und das Skript ausgeführtmyMainScript.R
. Das in Schritt 1 angegebene Code-Snippet oben inmyMainScript.R
legt die Fehlerbehandlungsoption für die nicht interaktive R-Sitzung fest.myMainScript.R
. Dies kann im Hauptskript selbst sein oder mehrere Funktionen tief verschachteln. Wenn der Fehler auftritt, wird die Behandlung wie in Schritt 1 angegeben ausgeführt und die R-Sitzung wird beendet.errorDump.rda
und ein Fehlerprotokoll mit dem Namenerror.log
werden in dem Verzeichnis erstellt, das in der'~/myUsername/directoryForDump'
Einstellung für die globale Fehlerbehandlungsoption angegeben ist .In Ihrer Freizeit inspizieren
error.log
Informationen über den Fehler zu überprüfen, einschließlich der Fehlermeldung selbst und der vollständigen Stack - Trace zu dem Fehler führt. Hier ist ein Beispiel für das Protokoll, das bei einem Fehler generiert wurde. Beachten Sie, dass die Zahlen nach dem#
Zeichen die Zeilennummern des Fehlers an verschiedenen Stellen im Aufrufstapel sind:Sie können nach Belieben mit
errorDump.rda
in eine interaktive R-Sitzung ladenload('~/path/to/errorDump.rda')
. Rufen Siedebugger(errorDump)
nach dem Laden auf, um alle R-Objekte im Speicher in einer der aktiven Umgebungen zu durchsuchen.debugger()
Weitere Informationen finden Sie in der R-Hilfe .Dieser Workflow ist enorm hilfreich, wenn Sie R in einer Produktionsumgebung ausführen, in der nicht interaktive R-Sitzungen über die Befehlszeile initiiert werden und Informationen über unerwartete Fehler beibehalten werden sollen. Die Möglichkeit, Speicher in eine Datei zu kopieren, mit der Sie den Arbeitsspeicher zum Zeitpunkt des Fehlers überprüfen können, sowie die Zeilennummern des Fehlers im Aufrufstapel ermöglichen ein schnelles Post-Mortem-Debugging der Fehlerursache.
quelle
Erst
options(show.error.locations = TRUE)
und danntraceback()
. Die Fehlerzeilennummer wird nach # angezeigtquelle