Wie kann ich mein Perl CGI-Skript beheben?

100

Ich habe ein Perl-Skript, das nicht funktioniert, und ich weiß nicht, wie ich das Problem eingrenzen soll. Was kann ich tun?


Hinweis: Ich füge die Frage hinzu, weil ich Stackoverflow wirklich meine sehr lange Antwort hinzufügen möchte. Ich verlinke in anderen Antworten immer wieder extern darauf und es verdient, hier zu sein. Scheuen Sie sich nicht, meine Antwort zu bearbeiten, wenn Sie etwas hinzufügen möchten.

brian d foy
quelle
5
@ Evan - mein Punkt ist einfach , dass selbst als Nicht-CW noch es ist editierbar - wenn Sie genug Karma haben; 100 für CW, 2k sonst. Jetzt, wo Sie 2060 haben, sollten Sie in der Lage sein, Nicht-CW-Beiträge zu bearbeiten.
Marc Gravell
1
@Evan, die magischen Punkte sind in den Tooltips in der rechten Spalte hier aufgelistet: stackoverflow.com/privileges
cjm
Wenn Ihr Webbrowser Zeilenrauschen anzeigt, druckt er möglicherweise stattdessen das Perl-Skript. In diesem Fall siehe stackoverflow.com/questions/2621161/…
Andrew Grimm

Antworten:

129

Diese Antwort ist als allgemeiner Rahmen für die Behebung von Problemen mit Perl-CGI-Skripten gedacht und wurde ursprünglich in Perlmonks als Fehlerbehebung bei Perl-CGI-Skripten angezeigt . Es ist weder eine vollständige Anleitung zu jedem Problem, auf das Sie stoßen könnten, noch ein Tutorial zum Squashing von Fehlern. Es ist nur der Höhepunkt meiner Erfahrung mit dem Debuggen von CGI-Skripten über zwanzig (plus!) Jahre. Diese Seite scheint viele verschiedene Häuser gehabt zu haben, und ich scheine zu vergessen, dass es sie gibt, also füge ich sie dem StackOverflow hinzu. Sie können mir Kommentare oder Vorschläge an [email protected] senden. Es ist auch Community-Wiki, aber nicht zu verrückt. :) :)


Verwenden Sie die integrierten Funktionen von Perl, um Probleme zu finden?

Aktivieren Sie Warnungen, damit Perl Sie vor fragwürdigen Teilen Ihres Codes warnt. Sie können dies über die Befehlszeile mit dem -wSchalter tun, sodass Sie keinen Code ändern oder jeder Datei ein Pragma hinzufügen müssen:

 % perl -w program.pl

Sie sollten sich jedoch zwingen, immer fragwürdigen Code zu löschen, indem Sie warningsallen Ihren Dateien das Pragma hinzufügen :

 use warnings;

Wenn Sie mehr Informationen als die kurze Warnmeldung benötigen, verwenden Sie das diagnosticsPragma, um weitere Informationen zu erhalten, oder lesen Sie die perldiag- Dokumentation:

 use diagnostics;

Haben Sie zuerst einen gültigen CGI-Header ausgegeben?

Der Server erwartet, dass die erste Ausgabe eines CGI-Skripts der CGI-Header ist. In der Regel ist dies so einfach wie print "Content-type: text/plain\n\n";oder mit CGI.pm und seinen Derivaten print header(). Einige Server reagieren empfindlich auf Fehlerausgaben (ein STDERR), die vor der Standardausgabe (ein ) angezeigt werden STDOUT.

Versuchen Sie, Fehler an den Browser zu senden

Fügen Sie diese Zeile hinzu

 use CGI::Carp 'fatalsToBrowser';

zu Ihrem Skript. Dadurch werden auch Kompilierungsfehler an das Browserfenster gesendet. Entfernen Sie dies unbedingt, bevor Sie in eine Produktionsumgebung wechseln, da die zusätzlichen Informationen ein Sicherheitsrisiko darstellen können.

Was hat das Fehlerprotokoll gesagt?

Server führen Fehlerprotokolle (oder sollten es zumindest). Dort sollte eine Fehlerausgabe vom Server und von Ihrem Skript angezeigt werden. Suchen Sie das Fehlerprotokoll und sehen Sie, was darin steht. Es gibt keinen Standardplatz für Protokolldateien. Suchen Sie in der Serverkonfiguration nach ihrem Speicherort oder fragen Sie den Serveradministrator. Sie können auch Tools wie CGI :: Carp verwenden , um Ihre eigenen Protokolldateien zu speichern.

Was sind die Berechtigungen des Skripts?

Wenn Fehler wie "Berechtigung verweigert" oder "Methode nicht implementiert" angezeigt werden, bedeutet dies wahrscheinlich, dass Ihr Skript vom Webserverbenutzer nicht lesbar und ausführbar ist. Bei Unix-Versionen wird empfohlen, den Modus auf 755 zu ändern : chmod 755 filename. Stellen Sie niemals einen Modus auf 777 ein!

Benutzt du use strict?

Denken Sie daran, dass Perl bei der ersten Verwendung automatisch Variablen erstellt. Dies ist eine Funktion, kann jedoch manchmal Fehler verursachen, wenn Sie einen Variablennamen falsch eingeben. Das Pragma use stricthilft Ihnen dabei, diese Art von Fehlern zu finden. Es ist ärgerlich, bis Sie sich daran gewöhnt haben, aber Ihre Programmierung wird sich nach einer Weile erheblich verbessern und Sie können verschiedene Fehler machen.

Kompiliert das Skript?

Sie können mit dem -c Schalter nach Kompilierungsfehlern suchen . Konzentrieren Sie sich auf die ersten gemeldeten Fehler. Spülen, wiederholen. Wenn Sie wirklich seltsame Fehler erhalten, überprüfen Sie, ob Ihr Skript die richtigen Zeilenenden hat. Wenn Sie im Binärmodus FTP ausführen, aus CVS auschecken oder etwas anderes, das die Übersetzung am Zeilenende nicht verarbeitet, sieht der Webserver Ihr Skript möglicherweise als eine große Zeile. Übertragen Sie Perl-Skripte im ASCII-Modus.

Beschwert sich das Skript über unsichere Abhängigkeiten?

Wenn sich Ihr Skript über unsichere Abhängigkeiten beschwert, verwenden Sie wahrscheinlich den -TSchalter, um den Taint-Modus zu aktivieren. Dies ist eine gute Sache, da Sie weiterhin ungeprüfte Daten an die Shell übergeben. Wenn es sich beschwert, macht es seine Arbeit, um uns zu helfen, sicherere Skripte zu schreiben. Alle Daten, die von außerhalb des Programms (dh der Umgebung) stammen, gelten als fehlerhaft. Umgebungsvariablen wie PATHund LD_LIBRARY_PATH sind besonders problematisch. Sie müssen diese auf einen sicheren Wert setzen oder sie vollständig deaktivieren, wie ich empfehle. Sie sollten sowieso absolute Pfade verwenden. Wenn sich die Verschmutzungsprüfung über etwas anderes beschwert, stellen Sie sicher, dass Sie die Daten nicht beschmutzt haben. Weitere Informationen finden Sie in der Perlsec- Manpage.

Was passiert, wenn Sie es über die Befehlszeile ausführen?

Gibt das Skript das aus, was Sie erwarten, wenn es über die Befehlszeile ausgeführt wird? Wird der Header zuerst ausgegeben, gefolgt von einer Leerzeile? Denken Sie daran, dass dies STDERRmöglicherweise zusammengeführt wird, STDOUTwenn Sie sich in einem Terminal befinden (z. B. in einer interaktiven Sitzung), und aufgrund der Pufferung möglicherweise in einer durcheinandergebrachten Reihenfolge angezeigt wird. Aktivieren Sie die Autoflush-Funktion von Perl, indem Sie $|einen echten Wert festlegen . Normalerweise wird dies $|++;in CGI-Programmen angezeigt. Einmal eingestellt, geht jeder Druck und jedes Schreiben sofort zur Ausgabe, anstatt gepuffert zu werden. Sie müssen dies für jedes Dateihandle einstellen. Verwenden Sie selectdiese Option, um das Standard-Dateihandle wie folgt zu ändern:

$|++;                            #sets $| for STDOUT
$old_handle = select( STDERR );  #change to STDERR
$|++;                            #sets $| for STDERR
select( $old_handle );           #change back to STDOUT

In jedem Fall sollte als erstes der CGI-Header gefolgt von einer Leerzeile ausgegeben werden.

Was passiert, wenn Sie es über die Befehlszeile in einer CGI-ähnlichen Umgebung ausführen?

Die Webserverumgebung ist normalerweise viel eingeschränkter als Ihre Befehlszeilenumgebung und enthält zusätzliche Informationen zu der Anforderung. Wenn Ihr Skript über die Befehlszeile einwandfrei ausgeführt wird, können Sie versuchen, eine Webserverumgebung zu simulieren. Wenn das Problem auftritt, liegt ein Umgebungsproblem vor.

Deaktivieren oder entfernen Sie diese Variablen

  • PATH
  • LD_LIBRARY_PATH
  • alle ORACLE_*Variablen

Stellen Sie diese Variablen ein

  • REQUEST_METHOD(auf GET, HEADoder POSTwie geeignet)
  • SERVER_PORT (normalerweise auf 80 eingestellt)
  • REMOTE_USER (wenn Sie Sachen mit geschütztem Zugriff machen)

Neuere Versionen von CGI.pm(> 2.75) erfordern, dass das -debugFlag das alte (nützliche) Verhalten erhält, sodass Sie es möglicherweise zu Ihren CGI.pmImporten hinzufügen müssen .

use CGI qw(-debug)

Benutzt du die()oder warn?

Diese Funktionen werden gedruckt, STDERRsofern Sie sie nicht neu definiert haben. Sie geben auch keinen CGI-Header aus. Sie können die gleiche Funktionalität mit Paketen wie CGI :: Carp erhalten

Was passiert, nachdem Sie den Browser-Cache geleert haben?

Wenn Sie der Meinung sind, dass Ihr Skript das Richtige tut und Sie die Anforderung manuell ausführen, erhalten Sie die richtige Ausgabe. Möglicherweise ist der Browser der Schuldige. Leeren Sie den Cache und setzen Sie die Cache-Größe beim Testen auf Null. Denken Sie daran, dass einige Browser wirklich dumm sind und keine neuen Inhalte neu laden, obwohl Sie dies anweisen. Dies ist besonders häufig der Fall, wenn der URL-Pfad identisch ist, sich der Inhalt jedoch ändert (z. B. dynamische Bilder).

Ist das Skript dort, wo Sie denken, dass es ist?

Der Dateisystempfad zu einem Skript steht nicht unbedingt in direktem Zusammenhang mit dem URL-Pfad zum Skript. Stellen Sie sicher, dass Sie das richtige Verzeichnis haben, auch wenn Sie ein kurzes Testskript schreiben müssen, um dies zu testen. Sind Sie außerdem sicher, dass Sie die richtige Datei ändern? Wenn Sie bei Ihren Änderungen keine Auswirkungen sehen, ändern Sie möglicherweise eine andere Datei oder laden eine Datei an die falsche Stelle hoch. (Dies ist übrigens meine häufigste Ursache für solche Probleme;)

Verwenden Sie CGI.pmoder ein Derivat davon?

Wenn Ihr Problem bezieht sich die CGI - Eingabe zu parsen und Sie sind nicht ein weit getestetes Modul wie mit CGI.pm, CGI::Request, CGI::Simpleoder CGI::Lite, um das Modul verwenden und mit dem Leben auszukommen. CGI.pmverfügt über einen cgi-lib.plKompatibilitätsmodus, mit dem Sie Eingabeprobleme aufgrund älterer CGI-Parser-Implementierungen lösen können.

Hast du absolute Pfade benutzt?

Wenn Sie externe Befehle mit system, Back-Ticks oder anderen IPC-Funktionen ausführen , sollten Sie einen absoluten Pfad zum externen Programm verwenden. Sie wissen nicht nur genau, was Sie ausführen, sondern vermeiden auch einige Sicherheitsprobleme. Wenn Sie Dateien zum Lesen oder Schreiben öffnen, verwenden Sie einen absoluten Pfad. Das CGI-Skript hat möglicherweise eine andere Vorstellung vom aktuellen Verzeichnis als Sie. Alternativ können Sie eine explizite chdir()Aktion ausführen , um Sie an den richtigen Ort zu bringen.

Haben Sie Ihre Rückgabewerte überprüft?

Die meisten Perl-Funktionen zeigen an, ob sie funktioniert haben oder nicht, und setzen $!auf Fehler. Haben Sie den Rückgabewert überprüft und $!auf Fehlermeldungen überprüft ? Haben Sie überprüft, $@ob Sie verwendet haben eval?

Welche Perl-Version verwenden Sie?

Die neueste stabile Version von Perl ist 5.28 (oder nicht, je nachdem, wann diese zuletzt bearbeitet wurde). Verwenden Sie eine ältere Version? Verschiedene Versionen von Perl haben möglicherweise unterschiedliche Vorstellungen von Warnungen.

Welchen Webserver verwenden Sie?

Verschiedene Server können in derselben Situation unterschiedlich handeln. Das gleiche Serverprodukt kann bei verschiedenen Konfigurationen unterschiedlich funktionieren. Nehmen Sie so viele dieser Informationen wie möglich in jede Hilfeanforderung auf.

Haben Sie die Serverdokumentation überprüft?

Seriöse CGI-Programmierer sollten so viel wie möglich über den Server wissen - einschließlich nicht nur der Serverfunktionen und des Serververhaltens, sondern auch der lokalen Konfiguration. Die Dokumentation für Ihren Server steht Ihnen möglicherweise nicht zur Verfügung, wenn Sie ein kommerzielles Produkt verwenden. Andernfalls sollte sich die Dokumentation auf Ihrem Server befinden. Wenn dies nicht der Fall ist, suchen Sie im Web danach.

Haben Sie die Archive von durchsucht comp.infosystems.www.authoring.cgi?

Dies war früher nützlich, aber alle guten Plakate sind entweder gestorben oder abgewandert.

Es ist wahrscheinlich, dass jemand Ihr Problem schon einmal hatte und dass jemand (möglicherweise ich) es in dieser Newsgroup beantwortet hat. Obwohl diese Newsgroup ihre Blütezeit hinter sich hat, kann die gesammelte Weisheit aus der Vergangenheit manchmal nützlich sein.

Können Sie das Problem mit einem kurzen Testskript reproduzieren?

In großen Systemen kann es schwierig sein, einen Fehler aufzuspüren, da so viele Dinge passieren. Versuchen Sie, das Problemverhalten mit dem kürzestmöglichen Skript zu reproduzieren. Das Problem zu kennen ist der größte Teil der Lösung. Dies mag sicherlich zeitaufwändig sein, aber Sie haben das Problem noch nicht gefunden und haben keine Optionen mehr. :) :)

Hast du dich entschieden, einen Film anzusehen?

Ernsthaft. Manchmal sind wir so in das Problem verwickelt, dass wir eine "Wahrnehmungsverengung" (Tunnelblick) entwickeln. Wenn Sie eine Pause einlegen, eine Tasse Kaffee trinken oder ein paar Bösewichte in [Duke Nukem, Quake, Doom, Halo, COD] in die Luft jagen, erhalten Sie möglicherweise die neue Perspektive, die Sie benötigen, um das Problem erneut anzugehen.

Haben Sie das Problem ausgesprochen?

Wieder ernsthaft. Manchmal führt uns eine laute Erklärung des Problems zu unseren eigenen Antworten. Sprechen Sie mit dem Pinguin (Plüschtier), weil Ihre Mitarbeiter nicht zuhören. Wenn Sie sich für dieses ernsthafte Debugging-Tool interessieren (und ich empfehle es, wenn Sie das Problem bis jetzt noch nicht gefunden haben), lesen Sie vielleicht auch The Psychology of Computer Programming .

Brian D Foy
quelle
4
Scheuen Sie sich nicht, meine Antwort zu bearbeiten, wenn Sie etwas hinzufügen möchten.
Brian D Foy
Anscheinend möchten Sie möglicherweise den Link zu den CGI-Meta-FAQ entfernen. Wird 5.12.1 als "stabil" angesehen?
Schlange Plissken
1
Warum nicht $|=1statt $|++?
Reinierpost
Warum $|=1statt $|++? Es macht keinen wirklichen Unterschied und ist selbst dann $|magisch.
Brian D Foy
2
Gute Antwort, ich denke, es könnte erwähnenswert sein, dass einige dieser Lösungen nur zur Fehlerbehebung dienen und nicht in den Produktionscode aufgenommen werden sollten. use strictist im Allgemeinen jederzeit gut zu verwenden, während die Verwendung fatalsToBrowserin der Produktion möglicherweise nicht empfohlen wird, insbesondere wenn Sie sie verwenden die.
Vol7ron
10

Ich denke, CGI :: Debug ist ebenfalls erwähnenswert.

Mikael S.
quelle
Leider kann ich nur die Frage bearbeiten, nicht die Antworten.
Mikael S
7

Verwenden Sie beim Debuggen einen Fehlerhandler?

dieAnweisungen und andere schwerwiegende Laufzeit- und Kompilierungsfehler werden gedruckt STDERR, die schwer zu finden sind und mit Nachrichten von anderen Webseiten auf Ihrer Site in Konflikt gebracht werden können. Während Sie Ihr Skript debuggen, ist es eine gute Idee, die schwerwiegenden Fehlermeldungen irgendwie in Ihrem Browser anzuzeigen.

Eine Möglichkeit, dies zu tun, besteht darin, anzurufen

   use CGI::Carp qw(fatalsToBrowser);

oben in Ihrem Skript. Dieser Aufruf installiert einen $SIG{__DIE__}Handler (siehe Perlvar ), der schwerwiegende Fehler in Ihrem Browser anzeigt und ihm gegebenenfalls einen gültigen Header voranstellt. Ein weiterer CGI-Debugging-Trick, den ich verwendet habe, bevor ich jemals davon gehört habe, CGI::Carpwar die Verwendung evalder DATAund __END__-Funktionen im Skript, um Fehler bei der Kompilierung abzufangen:

   #!/usr/bin/perl
   eval join'', <DATA>;
   if ($@) { print "Content-type: text/plain:\n\nError in the script:\n$@\n; }
   __DATA__
   # ... actual CGI script starts here

Diese ausführlichere Technik hat einen kleinen Vorteil gegenüber der Tatsache, CGI::Carpdass mehr Fehler bei der Kompilierung abgefangen werden.

Update: Ich habe es noch nie benutzt, aber es sieht so aus CGI::Debug, als wäre es , wie Mikael S vorgeschlagen hat, auch ein sehr nützliches und konfigurierbares Werkzeug für diesen Zweck.

Mob
quelle
3
@Ether: <DATA>ist ein magisches Dateihandle, das das aktuelle Skript beginnend mit liest __END__. Join stellt den Listenkontext bereit, sodass <fh> ein Array zurückgibt, eine Zeile pro Element. Dann setzt join es wieder zusammen (verbindet es mit ''). Zum Schluss eval.
Derobert
@Ether: Eine besser lesbare Möglichkeit, Zeile 2 zu schreiben, wäre:eval join(q{}, <DATA>);
derobert
@derobert: Eigentlich ist __DATA__ das Token, mit dem der Datenabschnitt gestartet wird, nicht __END__ (ich denke, das war meine Verwirrung).
Ether
1
@Ether: Nun, eigentlich arbeiten beide im Top-Level-Skript (laut Perldata-Manpage). Da jedoch DATA bevorzugt wird, habe ich die Antwort geändert.
Derobert
@derobert: danke für den doc link; Ich wusste nichts über das Abwärtskompatibilitätsverhalten von __END__!
Ether
7

Ich frage mich , wie kommt niemand die erwähnte PERLDB_OPTSOption genannt RemotePort; Zugegeben , es gibt nicht viele Arbeitsbeispiele im Web ( RemotePortwird nicht einmal in Perldebug erwähnt ) - und es war ein bisschen problematisch für mich, dieses zu finden, aber hier ist es (es ist ein Linux-Beispiel).

Um ein richtiges Beispiel zu machen, brauchte ich zuerst etwas, das eine sehr einfache Simulation eines CGI-Webservers durchführen kann, vorzugsweise über eine einzige Befehlszeile. Nachdem Sie den einfachen Befehlszeilen-Webserver zum Ausführen von cgis gefunden haben. (perlmonks.org) fand ich, dass der IO :: All - A Tiny Web Server für diesen Test geeignet ist .

Hier werde ich im /tmpVerzeichnis arbeiten; Das CGI-Skript wird /tmp/test.pl(siehe unten). Beachten Sie, dass der IO::AllServer nur ausführbare Dateien im selben Verzeichnis wie CGI bereitstellt. Dies chmod +x test.plist hier erforderlich. Um den üblichen CGI-Testlauf durchzuführen, wechsle ich /tmpin das Verzeichnis im Terminal und führe dort den einzeiligen Webserver aus:

$ cd /tmp
$ perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'

Der Webserver-Befehl wird im Terminal blockiert und startet den Webserver ansonsten lokal (unter 127.0.0.1 oder localhost). Danach kann ich zu einem Webbrowser gehen und diese Adresse anfordern:

http://127.0.0.1:8080/test.pl

... und ich sollte die prints beobachten, die durch test.plLaden - und Anzeigen - im Webbrowser erstellt wurden.


Um dieses Skript zu debuggen RemotePort, benötigen wir zunächst einen Listener im Netzwerk, über den wir mit dem Perl-Debugger interagieren. Wir können das Kommandozeilen-Tool verwenden netcat( nchaben das hier gesehen: Perl 如何 Remote-Debug? ). Führen Sie den netcatListener also zuerst in einem Terminal aus - wo er blockiert und auf Verbindungen auf Port 7234 wartet (der unser Debug-Port sein wird):

$ nc -l 7234

Dann möchten wir perlim Debug-Modus mit starten RemotePort, wenn der test.plaufgerufen wurde (auch im CGI-Modus über den Server). Dies, in Linux kann mit dem folgenden „shebang Wrapper“ Skript durchgeführt werden - was auch hier in sein muss /tmp, und muss ausführbar gemacht werden:

cd /tmp

cat > perldbgcall.sh <<'EOF'
#!/bin/bash
PERLDB_OPTS="RemotePort=localhost:7234" perl -d -e "do '$@'"
EOF

chmod +x perldbgcall.sh

Dies ist eine knifflige Sache - siehe Shell-Skript - Wie kann ich Umgebungsvariablen in meinem Shebang verwenden? - Unix & Linux Stack Exchange . Der Trick hier scheint jedoch nicht darin zu bestehen, den perlInterpreter, der damit umgeht, zu test.pl verzweigen. Wenn wir ihn also einmal getroffen haben, tun wir dies nicht exec, sondern rufen perl"einfach" auf und "quellen" unser test.plSkript im Grunde genommen mit do(siehe Wie führe ich ein aus?) Perl-Skript aus einem Perl-Skript heraus? ).

Jetzt, da wir perldbgcall.shin /tmp- wir das ändern können test.plDatei, so dass es auf seiner Shebang - Zeile (statt der üblichen Perl - Interpreter) auf diese ausführbare Datei verweist - hier wird /tmp/test.plgeändert so:

#!./perldbgcall.sh

# this is test.pl

use 5.10.1;
use warnings;
use strict;

my $b = '1';
my $a = sub { "hello $b there" };
$b = '2';
print "YEAH " . $a->() . " CMON\n";
$b = '3';
print "CMON " . &$a . " YEAH\n";

$DB::single=1;  # BREAKPOINT

$b = '4';
print "STEP " . &$a . " NOW\n";
$b = '5';
print "STEP " . &$a . " AGAIN\n";

Jetzt sind beide test.plund sein neuer Shebang-Handler perldbgcall.shin /tmp; und wir ncwarten auf Debug-Verbindungen an Port 7234 - damit wir endlich ein anderes Terminalfenster öffnen, das Verzeichnis in ändern /tmpund den einzeiligen Webserver (der auf Webverbindungen an Port 8080 wartet) ausführen können:

cd /tmp
perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'

Danach können wir zu unserem Webbrowser gehen und dieselbe Adresse anfordern http://127.0.0.1:8080/test.pl. Wenn der Webserver nun versucht, das Skript auszuführen, perldbgcall.shgeschieht dies jedoch über shebang, das perlim Remote-Debugger-Modus gestartet wird . Daher wird die Skriptausführung angehalten - und der Webbrowser wird gesperrt und wartet auf Daten. Wir können jetzt zum netcatTerminal wechseln und sollten den bekannten Perl-Debugger-Text sehen - jedoch ausgegeben durch nc:

$ nc -l 7234

Loading DB routines from perl5db.pl version 1.32
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(-e:1):   do './test.pl'
  DB<1> r
main::(./test.pl:29):   $b = '4';
  DB<1>

Wie das Snippet zeigt, verwenden wir es jetzt im Grunde genommen ncals "Terminal" - also können wir r"run" eingeben (und eingeben) - und das Skript wird ausgeführt, um die Haltepunktanweisung auszuführen (siehe auch In Perl, was ist der Unterschied zwischen $ DB :: single = 1 und 2? ), Bevor Sie erneut anhalten (beachten Sie, dass der Browser an dieser Stelle weiterhin gesperrt ist).

So, jetzt können wir sagen, Schritt für Schritt durch den Rest test.pldurch das ncTerminal:

....
main::(./test.pl:29):   $b = '4';
  DB<1> n
main::(./test.pl:30):   print "STEP " . &$a . " NOW\n";
  DB<1> n
main::(./test.pl:31):   $b = '5';
  DB<1> n
main::(./test.pl:32):   print "STEP " . &$a . " AGAIN\n";
  DB<1> n
Debugged program terminated.  Use q to quit or R to restart,
  use o inhibit_exit to avoid stopping after program termination,
  h q, h R or h o to get additional info.
  DB<1>

... aber auch an dieser Stelle sperrt der Browser und wartet auf Daten. Erst nachdem wir den Debugger beendet haben mit q:

  DB<1> q
$

... stoppt der Browser das Sperren - und zeigt schließlich die (vollständige) Ausgabe von test.pl:

YEAH hello 2 there CMON
CMON hello 3 there YEAH
STEP hello 4 there NOW
STEP hello 5 there AGAIN

Natürlich kann diese Art von Debugging auch ohne Ausführen des Webservers durchgeführt werden. Das Schöne dabei ist jedoch, dass wir den Webserver überhaupt nicht berühren. Wir lösen die Ausführung "nativ" (für CGI) über einen Webbrowser aus - und die einzige Änderung, die im CGI-Skript selbst erforderlich ist, ist die Änderung von shebang (und natürlich das Vorhandensein des shebang-Wrapper-Skripts als ausführbare Datei in derselben) Verzeichnis).

Nun, ich hoffe, das hilft jemandem - ich wäre sicher gerne darauf gestoßen, anstatt es selbst zu schreiben. :)
Prost!

sdaau
quelle
5

Für mich benutze ich log4perl . Es ist sehr nützlich und einfach.

use Log::Log4perl qw(:easy);

Log::Log4perl->easy_init( { level   => $DEBUG, file    => ">>d:\\tokyo.log" } );

my $logger = Log::Log4perl::get_logger();

$logger->debug("your log message");
zawhtut
quelle
1

Ehrlich gesagt können Sie all die lustigen Dinge über diesem Beitrag tun. Trotzdem war die einfachste und proaktivste Lösung, die ich gefunden habe, einfach "zu drucken".

Im Beispiel: (Normaler Code)

`$somecommand`;

Um zu sehen, ob es das tut, was ich wirklich möchte: (Fehlerbehebung)

print "$somecommand";
Ilan Kleiman
quelle
1

Es ist wahrscheinlich auch erwähnenswert, dass Perl Ihnen immer mitteilt, in welcher Zeile der Fehler auftritt, wenn Sie das Perl-Skript über die Befehlszeile ausführen. (Eine SSH-Sitzung zum Beispiel)

Ich werde dies normalerweise tun, wenn alles andere fehlschlägt. Ich werde SSH in den Server und das Perl-Skript manuell ausführen. Beispielsweise:

% perl myscript.cgi 

Wenn es ein Problem gibt, wird Perl Sie darüber informieren. Diese Debugging-Methode beseitigt alle Probleme im Zusammenhang mit Dateiberechtigungen oder Webbrowsern oder Webservern.

gpowr
quelle
Perl teilt Ihnen nicht immer die Zeilennummer mit, in der ein Fehler auftritt. Es zeigt Ihnen die Zeilennummer, in der festgestellt wird, dass etwas nicht stimmt. Der Fehler ist wahrscheinlich bereits aufgetreten.
Brian D Foy
0

Sie können das Perl-CGI-Skript im Terminal mit dem folgenden Befehl ausführen

 $ perl filename.cgi

Es interpretiert den Code und liefert das Ergebnis mit HTML-Code. Es meldet den Fehler, falls vorhanden.

D.Karthikeyan
quelle
1
Der Befehl $ perl -c filename.cgi überprüft leider die Syntax des Codes und meldet den Fehler, falls vorhanden. Es wird keinen HTML-Code des CGI bereitstellen.
D.Karthikeyan
Beim Aufrufen perl -c filenamewird in der Tat nur die Syntax überprüft. Druckt perl filenameaber die HTML-Ausgabe. Es ist keine Garantie, dass es keinen 500-CGI-Fehler gibt, aber es ist ein guter erster Test.
Nagev