Jak mogę rozwiązać problemy ze skryptem Perl CGI?

100

Mam skrypt Perla, który nie działa i nie wiem, jak zawęzić problem. Co mogę zrobić?


Uwaga: dodaję pytanie, ponieważ naprawdę chcę dodać moją bardzo długą odpowiedź do Stackoverflow. Wciąż łączę się z nim w innych odpowiedziach i zasługuje na to, aby tu być. Nie wstydź się edytować mojej odpowiedzi, jeśli masz coś do dodania.

brian d foy
źródło
5
@Evan - chodzi mi po prostu o to, że nawet jeśli nie jest CW, nadal można go edytować - jeśli masz wystarczająco dużo karmy; 100 dla CW, 2k w innym przypadku. Więc teraz masz 2060, powinieneś być w stanie edytować posty nie-CW.
Marc Gravell
1
@Evan, magiczne punkty są wymienione w podpowiedziach w prawej kolumnie tutaj: stackoverflow.com/privileges
cjm
Jeśli Twoja przeglądarka internetowa wyświetla szum linii, być może zamiast tego drukuje skrypt Perla. W takim przypadku zobacz stackoverflow.com/questions/2621161/…
Andrew Grimm,

Odpowiedzi:

129

Ta odpowiedź ma służyć jako ogólne ramy do rozwiązywania problemów ze skryptami Perl CGI i pierwotnie pojawiła się w Perlmonks jako Rozwiązywanie problemów ze skryptami Perl CGI . Nie jest to kompletny przewodnik po każdym napotkanym problemie ani samouczek dotyczący usuwania błędów. To tylko kulminacja mojego doświadczenia w debugowaniu skryptów CGI przez dwadzieścia (plus!) Lat. Wygląda na to, że ta strona miała wiele różnych domów i wydaje mi się, że zapomniałem, że istnieje, więc dodaję ją do StackOverflow. Możesz przesłać mi wszelkie uwagi lub sugestie na adres [email protected]. To także wiki społeczności, ale nie zwariuj. :)


Czy używasz wbudowanych funkcji Perla, aby pomóc Ci znaleźć problemy?

Włącz ostrzeżenia, aby Perl ostrzegał Cię o wątpliwych częściach kodu. Możesz to zrobić z wiersza poleceń za pomocą -wprzełącznika, więc nie musisz zmieniać żadnego kodu ani dodawać pragmy do każdego pliku:

 % perl -w program.pl

Powinieneś jednak zmusić się do zawsze wyjaśniania wątpliwego kodu, dodając warningspragmę do wszystkich swoich plików:

 use warnings;

Jeśli potrzebujesz więcej informacji niż krótki komunikat ostrzegawczy, skorzystaj z diagnosticspragmy, aby uzyskać więcej informacji, lub zajrzyj do dokumentacji perldiag :

 use diagnostics;

Czy najpierw wyprowadziłeś prawidłowy nagłówek CGI?

Serwer oczekuje, że pierwszym wyjściem ze skryptu CGI będzie nagłówek CGI. Typowo, które mogą być proste, jak print "Content-type: text/plain\n\n";i z CGI.pm i jego pochodnych print header(). Niektóre serwery są wrażliwe na błąd wyjścia (on STDERR) pojawiający się przed standardowym wyjściem (on STDOUT).

Spróbuj wysłać błędy do przeglądarki

Dodaj tę linię

 use CGI::Carp 'fatalsToBrowser';

do swojego skryptu. Spowoduje to również wysłanie błędów kompilacji do okna przeglądarki. Pamiętaj, aby usunąć to przed przejściem do środowiska produkcyjnego, ponieważ dodatkowe informacje mogą stanowić zagrożenie dla bezpieczeństwa.

Co zawiera dziennik błędów?

Serwery przechowują dzienniki błędów (a przynajmniej powinny). Powinien tam pojawić się błąd wyjściowy z serwera i skryptu. Znajdź dziennik błędów i zobacz, co zawiera. Nie ma standardowego miejsca na pliki dziennika. Sprawdź w konfiguracji serwera ich lokalizację lub zapytaj administratora serwera. Możesz także użyć narzędzi takich jak CGI :: Carp aby zachować własne pliki dziennika.

Jakie są uprawnienia skryptu?

Jeśli widzisz błędy, takie jak „Odmowa uprawnień” lub „Metoda nie zaimplementowana”, prawdopodobnie oznacza to, że Twój skrypt nie jest czytelny i nie może być wykonywany przez użytkownika serwera WWW. W przypadku wersji Unix zaleca się zmianę trybu na 755: chmod 755 filename . Nigdy nie ustawiaj trybu na 777!

Czy używasz use strict ?

Pamiętaj, że Perl automatycznie tworzy zmienne, gdy używasz ich po raz pierwszy. Jest to funkcja, ale czasami może powodować błędy, jeśli błędnie wpiszesz nazwę zmiennej. Pragma use strict pomoże ci znaleźć tego rodzaju błędy. Jest to denerwujące, dopóki się do tego nie przyzwyczaisz, ale po pewnym czasie programowanie znacznie się poprawi i będziesz mógł popełniać różne błędy.

Czy skrypt się kompiluje?

Możesz sprawdzić błędy kompilacji za pomocą -c przełącznika. Skoncentruj się na pierwszych zgłoszonych błędach. Spłucz, powtórz. Jeśli otrzymujesz naprawdę dziwne błędy, sprawdź, czy Twój skrypt ma prawidłowe zakończenia linii. Jeśli korzystasz z FTP w trybie binarnym, wyewidencjonujesz z CVS lub coś innego, co nie obsługuje tłumaczenia końca linii, serwer WWW może zobaczyć twój skrypt jako jedną dużą linię. Prześlij skrypty Perla w trybie ASCII.

Czy skrypt narzeka na niezabezpieczone zależności?

Jeśli twój skrypt narzeka na niezabezpieczone zależności, prawdopodobnie używasz -Tprzełącznika do włączania trybu skażenia, co jest dobrą rzeczą, ponieważ zapewnia przekazywanie niezaznaczonych danych do powłoki. Jeśli narzeka, wykonuje swoją pracę, pomagając nam pisać bezpieczniejsze skrypty. Wszelkie dane pochodzące spoza programu (tj. Ze środowiska) są uważane za skażone. Zmienne środowiskowe, takie jak PATHi LD_LIBRARY_PATH są szczególnie kłopotliwe. Musisz ustawić je na bezpieczną wartość lub całkowicie je wyłączyć, tak jak zalecam. I tak powinieneś używać ścieżek bezwzględnych. Jeśli sprawdzanie skażeń narzeka na coś innego, upewnij się, że dane zostały oczyszczone. Szczegółowe informacje można znaleźć na stronie podręcznika perlsec .

Co się stanie, gdy uruchomisz go z wiersza poleceń?

Czy skrypt wyświetla to, czego oczekujesz po uruchomieniu z wiersza poleceń? Czy najpierw wyjście nagłówka, po którym następuje pusty wiersz? Pamiętaj, że STDERRmoże zostać scalone z, STDOUT jeśli jesteś na terminalu (np. Sesja interaktywna), a ze względu na buforowanie może pojawić się w pomieszanej kolejności. Włącz funkcję autoflush Perla, ustawiając $|wartość true. Zwykle można to zobaczyć $|++;w programach CGI. Po ustawieniu każde drukowanie i zapis będzie natychmiast trafiać na wyjście, a nie być buforowane. Musisz to ustawić dla każdego uchwytu pliku. Użyj, selectaby zmienić domyślny uchwyt pliku, na przykład:

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

Tak czy inaczej, pierwszym wyjściem powinien być nagłówek CGI, po którym powinien znajdować się pusty wiersz.

Co się stanie, gdy uruchomisz go z wiersza poleceń w środowisku podobnym do CGI?

Środowisko serwera WWW jest zwykle dużo bardziej ograniczone niż środowisko wiersza poleceń i zawiera dodatkowe informacje o żądaniu. Jeśli twój skrypt działa dobrze z wiersza poleceń, możesz spróbować zasymulować środowisko serwera WWW. Jeśli pojawi się problem, masz problem ze środowiskiem.

Cofnij ustawienie lub usuń te zmienne

  • PATH
  • LD_LIBRARY_PATH
  • wszystkie ORACLE_*zmienne

Ustaw te zmienne

  • REQUEST_METHOD(wartość GET, HEADlubPOST , jak w tym przypadku)
  • SERVER_PORT (zwykle ustawione na 80)
  • REMOTE_USER (jeśli robisz rzeczy z chronionym dostępem)

Najnowsze wersje CGI.pm(> 2.75) wymagają -debugflagi, aby uzyskać stare (przydatne) zachowanie, więc może być konieczne dodanie jej do CGI.pmimportu.

use CGI qw(-debug)

Czy używasz die()lubwarn ?

Te funkcje są drukowane, STDERRchyba że zostały przedefiniowane. Nie wyświetlają też nagłówka CGI. Możesz uzyskać tę samą funkcjonalność dzięki pakietom takim jak CGI :: Carp

Co się dzieje po wyczyszczeniu pamięci podręcznej przeglądarki?

Jeśli uważasz, że twój skrypt działa właściwie, a gdy wykonujesz żądanie ręcznie, otrzymasz odpowiednie dane wyjściowe, przyczyną może być przeglądarka. Wyczyść pamięć podręczną i ustaw jej rozmiar na zero podczas testowania. Pamiętaj, że niektóre przeglądarki są naprawdę głupie i nie ładują ponownie nowej zawartości, mimo że każesz im to zrobić. Jest to szczególnie powszechne w przypadkach, gdy ścieżka adresu URL jest taka sama, ale zmienia się zawartość (np. Dynamiczne obrazy).

Czy scenariusz jest tam, gdzie myślisz?

Ścieżka systemu plików do skryptu niekoniecznie jest bezpośrednio związana ze ścieżką adresu URL do skryptu. Upewnij się, że masz właściwy katalog, nawet jeśli musisz napisać krótki skrypt testowy, aby to przetestować. Ponadto, czy na pewno modyfikujesz właściwy plik? Jeśli nie widzisz żadnego efektu swoich zmian, być może modyfikujesz inny plik lub przesyłasz plik w niewłaściwe miejsce. (Nawiasem mówiąc, to moja najczęstsza przyczyna takich kłopotów;)

Używasz tego CGI.pmczy jest to pochodna?

Jeśli problem jest związany z parsowania wejście CGI i nie używasz szeroko przetestowany moduł jak CGI.pm, CGI::Request, CGI::Simplelub CGI::Liteużyć modułu i zabrać się za życia. CGI.pmmacgi-lib.pl tryb zgodności, który może pomóc w rozwiązywaniu problemów z wejściem ze względu na starsze implementacje parsera CGI.

Czy korzystałeś ze ścieżek bezwzględnych?

Jeśli używasz poleceń zewnętrznych z systemzaznaczeniami wstecznymi lub innymi udogodnieniami IPC, powinieneś użyć bezwzględnej ścieżki do programu zewnętrznego. Nie tylko wiesz dokładnie, co uruchamiasz, ale także unikasz niektórych problemów związanych z bezpieczeństwem. Jeśli otwierasz pliki do odczytu lub zapisu, użyj ścieżki bezwzględnej. Skrypt CGI może mieć inne pojęcie o bieżącym katalogu niż ty. Alternatywnie możesz zrobić wyraźną wiadomość, chdir()aby umieścić Cię we właściwym miejscu.

Czy sprawdziłeś wartości zwracane?

Większość funkcji Perla powie ci, czy zadziałały, czy nie, i ustawią się $!w przypadku awarii. Czy sprawdziłeś wartość zwracaną i sprawdziłeś $!komunikaty o błędach? Czy sprawdziłeś, $@czy używałeś eval?

Której wersji Perla używasz?

Najnowsza stabilna wersja Perla to 5.28 (lub nie, w zależności od tego, kiedy była ostatnio edytowana). Czy używasz starszej wersji? Różne wersje Perla mogą mieć różne koncepcje ostrzeżeń.

Z jakiego serwera WWW korzystasz?

W tej samej sytuacji różne serwery mogą działać inaczej. Ten sam produkt serwerowy może działać inaczej w różnych konfiguracjach. Uwzględnij jak najwięcej tych informacji w każdej prośbie o pomoc.

Czy sprawdziłeś dokumentację serwera?

Poważni programiści CGI powinni wiedzieć jak najwięcej o serwerze - w tym nie tylko o funkcjach i zachowaniu serwera, ale także o lokalnej konfiguracji. Dokumentacja serwera może nie być dostępna, jeśli używasz produktu komercyjnego. W przeciwnym razie dokumentacja powinna znajdować się na serwerze. Jeśli tak nie jest, poszukaj go w sieci.

Przeszukałeś archiwa comp.infosystems.www.authoring.cgi?

To zastosowanie ma być przydatne, ale wszystkie dobre plakaty albo umarły, albo odeszły.

Jest prawdopodobne, że ktoś miał już wcześniej twój problem i że ktoś (prawdopodobnie ja) odpowiedział na niego w tej grupie dyskusyjnej. Chociaż ta grupa dyskusyjna minęła swój okres świetności, zebrana wiedza z przeszłości może czasami być przydatna.

Czy możesz odtworzyć problem za pomocą krótkiego skryptu testowego?

W dużych systemach może być trudno wyśledzić błąd, ponieważ dzieje się tak wiele rzeczy. Spróbuj odtworzyć problematyczne zachowanie za pomocą możliwie najkrótszego skryptu. Znajomość problemu to większość rozwiązania. Może to być z pewnością czasochłonne, ale nie znalazłeś jeszcze problemu i wyczerpują się opcje. :)

Zdecydowałeś się obejrzeć film?

Poważnie. Czasami możemy być tak pochłonięci problemem, że rozwijamy „zwężenie percepcyjne” (widzenie tunelowe). Przerwa, wypicie filiżanki kawy lub zabicie złych facetów w [Duke Nukem, Quake, Doom, Halo, COD] może dać ci świeżą perspektywę, której potrzebujesz, aby ponownie podejść do problemu.

Czy wypowiedziałeś problem?

Poważnie znowu. Czasami głośne wyjaśnienie problemu prowadzi nas do własnych odpowiedzi. Porozmawiaj z pingwinem (pluszowa zabawka), ponieważ Twoi współpracownicy nie słuchają. Jeśli interesuje Cię to jako poważne narzędzie do debugowania (i polecam je, jeśli do tej pory nie znalazłeś problemu), możesz również przeczytać Psychologię programowania komputerowego .

brian d foy
źródło
4
Nie wstydź się edytować mojej odpowiedzi, jeśli masz coś do dodania.
brian d foy
Wygląda na to, że możesz chcieć usunąć odsyłacz do meta FAQ CGI. Czy wersja 5.12.1 jest uważana za „stabilną”?
Snake Plissken
1
Dlaczego nie $|=1zamiast $|++?
reinierpost
Dlaczego $|=1zamiast $|++? To naprawdę nie robi różnicy, a nawet wtedy $|jest magiczne.
brian d foy
2
Dobra odpowiedź, myślę, że warto wspomnieć, że niektóre z tych rozwiązań powinny służyć wyłącznie do rozwiązywania problemów i nie powinny być wprowadzane do kodu produkcyjnego. use strictjest ogólnie dobry w użyciu przez cały czas, podczas gdy używanie fatalsToBrowsermoże nie być zalecane w produkcji, zwłaszcza jeśli używasz die.
vol7ron
10

Myślę, że warto wspomnieć o CGI :: Debug .

Mikael S
źródło
Niestety mogę edytować tylko pytanie, a nie odpowiedzi.
Mikael S
7

Czy używasz modułu obsługi błędów podczas debugowania?

die instrukcje i inne krytyczne błędy czasu wykonywania i kompilacji są drukowane STDERR , co może być trudne do znalezienia i może być łączone z wiadomościami z innych stron internetowych w Twojej witrynie. Podczas debugowania skryptu warto w jakiś sposób wyświetlić komunikaty o błędach krytycznych w przeglądarce.

Jednym ze sposobów jest zadzwonienie

   use CGI::Carp qw(fatalsToBrowser);

u góry skryptu. To wywołanie zainstaluje program $SIG{__DIE__}obsługi (zobacz perlvar ) wyświetli krytyczne błędy w przeglądarce, dodając do niego poprawny nagłówek, jeśli to konieczne. Inną sztuczką związaną z debugowaniem CGI, której użyłem, zanim kiedykolwiek usłyszałem, CGI::Carpbyło użycie evalfunkcji DATAi __END__w skrypcie do wychwytywania błędów w czasie kompilacji:

   #!/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

Ta bardziej szczegółowa technika ma niewielką przewagę nad CGI::Carp , ponieważ wyłapuje więcej błędów w czasie kompilacji.

Aktualizacja: Nigdy go nie używałem, ale wygląda na to, że CGI::Debug, jak sugerował Mikael S, jest również bardzo przydatnym i konfigurowalnym narzędziem do tego celu.

mob
źródło
3
@Ether: <DATA>to magiczny uchwyt pliku, który czyta bieżący skrypt, zaczynając od __END__. Join dostarcza kontekst listy, więc <fh> zwraca tablicę, po jednym wierszu na element. Następnie złączenie składa go z powrotem (łącząc go za pomocą „”). Wreszcie eval.
derobert
@Ether: Bardziej czytelnym sposobem zapisu linii 2 byłoby:eval join(q{}, <DATA>);
derobert
@derobert: właściwie __DATA__ jest tokenem używanym do rozpoczęcia sekcji danych, a nie __END__ (myślę, że to było moje zamieszanie).
Eter
1
@Ether: Cóż, w rzeczywistości oba działają w skrypcie najwyższego poziomu (zgodnie ze stroną podręcznika perldata). Ale ponieważ preferowane są DANE , zmieniłem odpowiedź.
derobert
@derobert: dzięki za link do dokumentu; Nie wiedziałem o zachowaniu zgodności wstecznej __END__!
Eter
7

Zastanawiam się, dlaczego nikt nie wspomniał o PERLDB_OPTSopcji nazwanej RemotePort; chociaż trzeba przyznać, nie ma wielu działających przykładów w Internecie ( RemotePortnie ma nawet wzmianki o nich w perldebug ) - i było dla mnie trochę problematyczne wymyślenie tego, ale oto jest (jest to przykład Linuksa).

Aby zrobić dobry przykład, najpierw potrzebowałem czegoś, co może wykonać bardzo prostą symulację serwera WWW CGI, najlepiej za pomocą jednej linii poleceń. Po znalezieniu prostego serwera WWW wiersza poleceń do uruchamiania cgis. (perlmonks.org) , znalazłem IO :: All - A Tiny Web Server do zastosowania w tym teście.

Tutaj będę pracować w /tmpkatalogu; skrypt CGI zostanie /tmp/test.pl(dołączony poniżej). Zauważ, że IO::Allserwer będzie obsługiwał tylko pliki wykonywalne w tym samym katalogu co CGI, więc chmod +x test.pljest to wymagane tutaj. Tak więc, aby wykonać zwykły test CGI, zmieniam katalog na /tmpw terminalu i uruchamiam tam jednoliniowy serwer sieciowy:

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

Polecenie serwera sieciowego zablokuje się w terminalu, aw innym przypadku uruchomi serwer WWW lokalnie (na 127.0.0.1 lub localhost) - potem mogę przejść do przeglądarki internetowej i zażądać tego adresu:

http://127.0.0.1:8080/test.pl

... i powinienem obserwować prints wykonane przez test.plzaładowanie - i wyświetlenie - w przeglądarce internetowej.


Teraz, aby debugować ten skrypt RemotePort, najpierw potrzebujemy odbiornika w sieci, przez który będziemy współpracować z debugerem Perla; możemy użyć narzędzia wiersza poleceń netcat( ncwidziałeś to tutaj: Perl 如何 zdalny debug? ). Więc najpierw uruchom netcatnasłuchiwanie w jednym terminalu - gdzie będzie blokował i czekał na połączenia na porcie 7234 (który będzie naszym portem debugowania):

$ nc -l 7234

Następnie chcielibyśmy perlrozpocząć w trybie debugowania RemotePort, gdy test.plzostał wywołany (nawet w trybie CGI, za pośrednictwem serwera). W Linuksie można to zrobić za pomocą następującego skryptu "shebang wrapper" - który tutaj również musi być w programie /tmpi musi być wykonany:

cd /tmp

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

chmod +x perldbgcall.sh

To trochę podchwytliwe - zobacz skrypt powłoki - Jak mogę używać zmiennych środowiskowych w moim shebangu? - Wymiana stosów systemów Unix i Linux . Wydaje się jednak, że sztuczka polega na tym, aby nie rozwidlać perlinterpretera, który obsługuje test.pl - więc gdy już to zrobimy, nie robimy tego exec, ale zamiast tego nazywamy perl„wyraźnie” i zasadniczo „źródłem” naszego test.plskryptu, używając do(zobacz Jak uruchomić Skrypt Perla z poziomu skryptu Perla? ).

Teraz, gdy mamy już perldbgcall.shw /tmp- możemy zmienić test.plplik tak, aby odnosił się do tego pliku wykonywalnego w swojej linii shebang (zamiast zwykłego interpretera Perla) - tutaj jest /tmp/test.plzmodyfikowany w ten sposób:

#!./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";

Teraz, zarówno, jak test.pli jej nowy przewodnik perldbgcall.sh, są w środku /tmp; i ncnasłuchujemy połączeń debugowania na porcie 7234 - więc możemy w końcu otworzyć inne okno terminala, zmienić katalog na /tmpi uruchomić jednoliniowy serwer sieciowy (który będzie nasłuchiwał połączeń internetowych na porcie 8080):

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

Po wykonaniu tych czynności możemy przejść do naszej przeglądarki internetowej i żądać tego samego adresu http://127.0.0.1:8080/test.pl. Jednak teraz, gdy serwer sieciowy spróbuje wykonać skrypt, zrobi to poprzez perldbgcall.shshebang - który uruchomi się perlw trybie zdalnego debugera. W ten sposób wykonanie skryptu zostanie wstrzymane - a zatem przeglądarka internetowa zablokuje się, czekając na dane. Możemy teraz przełączyć się na netcatterminal i powinniśmy zobaczyć znajomy tekst debuggera Perla - jednak wyprowadzony przez 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>

Jak widać we fragmencie, używamy teraz zasadniczo ncjako „terminala” - więc możemy wpisać r(i Enter) dla „run” - a skrypt uruchomi się, wykonując instrukcję punktu przerwania (zobacz także W perlu, jaka jest różnica między $ DB :: single = 1 i 2? ), Przed ponownym zatrzymaniem (uwaga w tym momencie przeglądarka nadal się blokuje).

Więc teraz możemy, powiedzmy, przejść przez resztę test.pl, przez 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>

... jednak również w tym momencie przeglądarka blokuje się i czeka na dane. Dopiero po wyjściu z debuggera za pomocą q:

  DB<1> q
$

... czy przeglądarka przestaje się blokować - i na końcu wyświetla (kompletne) wyjście test.pl:

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

Oczywiście tego rodzaju debugowanie można przeprowadzić nawet bez uruchamiania serwera WWW - jednak fajną rzeczą jest to, że w ogóle nie dotykamy serwera WWW; uruchamiamy wykonanie „natywnie” (dla CGI) z przeglądarki internetowej - a jedyną zmianą potrzebną w samym skrypcie CGI jest zmiana shebang (i oczywiście obecność skryptu shebang wrapper, jako pliku wykonywalnego w tym samym informator).

Cóż, mam nadzieję, że to pomoże kogoś - na pewno by się spodobało, że natknęliśmy się na to, zamiast pisać to sam :)
Cheers!

sdaau
źródło
5

U mnie używam log4perl . Jest to całkiem przydatne i łatwe.

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
źródło
1

Szczerze mówiąc, możesz robić wszystkie fajne rzeczy powyżej tego postu. Chociaż najprostszym i najbardziej proaktywnym rozwiązaniem, jakie znalazłem, było po prostu „wydrukowanie”.

Na przykład: (Normalny kod)

`$somecommand`;

Aby sprawdzić, czy robi to, czego naprawdę chcę: (Rozwiązywanie problemów)

print "$somecommand";
Ilan Kleiman
źródło
1

Prawdopodobnie warto również wspomnieć, że Perl zawsze powie ci, w której linii wystąpił błąd, gdy wykonujesz skrypt Perla z wiersza poleceń. (Na przykład sesja SSH)

Zwykle robię to, jeśli wszystko inne zawiedzie. Będę SSH na serwerze i ręcznie uruchomię skrypt Perla. Na przykład:

% perl myscript.cgi 

Jeśli wystąpi problem, Perl Ci o tym poinformuje. Ta metoda debugowania eliminuje wszelkie problemy związane z uprawnieniami do plików lub problemy z przeglądarką internetową lub serwerem WWW.

gpowr
źródło
Perl nie zawsze podaje numer wiersza, w którym wystąpił błąd. Podaje numer linii, w której zdaje sobie sprawę, że coś jest nie tak. Prawdopodobnie błąd już się pojawił.
brian d foy
0

Możesz uruchomić skrypt perl cgi-script w terminalu za pomocą poniższego polecenia

 $ perl filename.cgi

Interpretuje kod i podaje wynik w postaci kodu HTML. Zgłosi błąd, jeśli wystąpi.

D.Karthikeyan
źródło
1
Przepraszamy, polecenie $ perl -c nazwa_pliku.cgi sprawdza poprawność składni kodu i zgłasza błąd, jeśli występuje. Nie zapewni kodu html cgi.
D. Karthikeyan,
Wywołanie perl -c filenamerzeczywiście sprawdzi tylko składnię. Ale perl filenamedrukuje wyjście HTML. Nie ma jednak gwarancji, że nie wystąpi błąd 500 CGI, ale to dobry pierwszy test.
Nagev