Perl CGI betiğimde nasıl sorun giderebilirim?


100

Çalışmayan bir Perl betiğim var ve sorunu nasıl daraltmaya başlayacağımı bilmiyorum. Ne yapabilirim?


Not: Soruyu ekliyorum çünkü gerçekten çok uzun yanıtımı Stackoverflow'a eklemek istiyorum. Diğer cevaplarda ona harici olarak bağlanmaya devam ediyorum ve burada olmayı hak ediyor. Ekleyecek bir şeyiniz varsa cevabımı düzenlemek konusunda utanmayın.


5
@Evan - benim açımdan bile olmayan CW olarak yine o basitçe olduğunu düzenlenebilir - eğer yeterince karması var; CW için 100, aksi takdirde 2k. Artık 2060'ınız var, CW olmayan gönderileri düzenleyebilmelisiniz.
Marc Gravell

1
@Evan, sihirli noktalar buradaki sağ sütundaki araç ipuçlarında listelenmiştir: stackoverflow.com/privileges
cjm

Web tarayıcınız satır gürültüsü gösteriyorsa, bunun yerine perl betiğini yazdırıyor olabilir. Bu durumda, stackoverflow.com/questions/2621161/… sayfasına
Andrew Grimm

Yanıtlar:


130

Bu cevap, Perl CGI betikleri ile ilgili problemler üzerinde çalışmak için genel bir çerçeve olarak tasarlanmıştır ve ilk olarak Perlmonks'ta Perl CGI Scriptlerinde Sorun Giderme olarak görünmüştür . Karşılaşabileceğiniz her sorun için eksiksiz bir rehber veya hata giderme hakkında bir eğitim değildir. Yirmi (artı!) Yıl boyunca CGI betiklerinde hata ayıklama deneyimimin doruk noktası. Bu sayfanın birçok farklı evi var gibi görünüyor ve var olduğunu unuttuğum için onu StackOverflow'a ekliyorum. Her türlü görüş ve önerinizi bdfoy@cpan.org adresinden bana iletebilirsiniz. Aynı zamanda topluluk wikisi, ama fazla delirmeyin. :)


Sorunları bulmanıza yardımcı olmak için Perl'in yerleşik özelliklerini kullanıyor musunuz?

Perl'in sizi kodunuzun şüpheli kısımları hakkında uyarmasına izin vermek için uyarıları açın. Bunu komut satırından -wanahtarla yapabilirsiniz, böylece herhangi bir kodu değiştirmeniz veya her dosyaya bir pragma eklemeniz gerekmez:

 % perl -w program.pl

Bununla birlikte, warningspragmayı tüm dosyalarınıza ekleyerek şüpheli kodu her zaman temizlemeye zorlamalısınız :

 use warnings;

Kısa uyarı mesajından daha fazla bilgiye ihtiyacınız varsa, diagnosticsdaha fazla bilgi almak için pragma kullanın veya perldiag belgelerine bakın:

 use diagnostics;

Önce geçerli bir CGI başlığı çıktınız mı?

Sunucu, bir CGI komut dizisinden ilk çıktının CGI başlığı olmasını bekliyor. Tipik olarak bu print "Content-type: text/plain\n\n";, CGI.pm ve türevleri kadar basit olabilir print header(). Bazı sunucular, STDERRstandart çıktıdan (açık STDOUT) önce gösterilen hata çıktısına (açık ) duyarlıdır .

Tarayıcıya hata göndermeyi deneyin

Bu satırı ekleyin

 use CGI::Carp 'fatalsToBrowser';

senaryonuza. Bu ayrıca tarayıcı penceresine derleme hataları gönderir. Ekstra bilgiler güvenlik riski oluşturabileceğinden, üretim ortamına geçmeden önce bunu kaldırdığınızdan emin olun.

Hata günlüğü ne dedi?

Sunucular hata günlüklerini tutar (veya en azından tutmalıdır). Sunucudan ve betiğinizden gelen hata çıktısı orada görünmelidir. Hata günlüğünü bulun ve ne yazdığını görün. Günlük dosyaları için standart bir yer yoktur. Konumları için sunucu yapılandırmasına bakın veya sunucu yöneticisine sorun. Kendi günlük dosyalarınızı saklamak için CGI :: Carp gibi araçları da kullanabilirsiniz .

Komut dosyasının izinleri nelerdir?

"İzin reddedildi" veya "Yöntem uygulanmadı" gibi hatalar görürseniz, bu muhtemelen komut dizinizin web sunucusu kullanıcısı tarafından okunamaz ve çalıştırılabilir olmadığı anlamına gelir. Unix tatlar günü, 755 'modunu değiştirerek önerilir: chmod 755 filename. Asla bir modu 777'ye ayarlamayın!

Kullandığınız use strict?

Perl'in değişkenleri ilk kullandığınızda otomatik olarak yarattığını unutmayın. Bu bir özelliktir, ancak bazen bir değişken adını yanlış yazarsanız hatalara neden olabilir. Pragma use strictbu tür hataları bulmanıza yardımcı olacaktır. Alışana kadar can sıkıcı bir durum, ancak programlamanız bir süre sonra önemli ölçüde gelişecek ve farklı hatalar yapmakta özgür olacaksınız.

Komut dosyası derleniyor mu?

-c Anahtarı kullanarak derleme hatalarını kontrol edebilirsiniz . Bildirilen ilk hatalara odaklanın. Durulayın, tekrarlayın. Gerçekten tuhaf hatalar alıyorsanız, komut dosyanızın doğru satır sonlarına sahip olduğundan emin olun. İkili modda FTP, CVS'den çıkış veya satır sonu çevirisini işlemeyen başka bir şey yaparsanız, web sunucusu komut dosyanızı tek bir büyük satır olarak görebilir. Perl komut dosyalarını ASCII modunda aktarın.

Senaryo güvensiz bağımlılıklardan mı şikayetçi?

Komut dosyanız güvensiz bağımlılıklardan şikayet ediyorsa, muhtemelen -Tbozuk kipi açmak için anahtarı kullanıyorsunuzdur , bu iyi bir şeydir çünkü kontrol edilmemiş verileri kabuğa aktarmanızı sağlar. Şikayet ediyorsa, daha güvenli komut dosyaları yazmamıza yardımcı olmak için işini yapıyor demektir. Programın dışından (yani çevreden) kaynaklanan herhangi bir veri bozuk kabul edilir. Gibi çevresel değişkenler PATHve LD_LIBRARY_PATH özellikle güçlük doğurmaktadır. Bunları güvenli bir değere ayarlamanız veya tavsiye ettiğim gibi tamamen kaldırmanız gerekir. Yine de mutlak yollar kullanmalısınız. Başka bir şey hakkında şikayetleri kontrol etmekte sorun yaşıyorsanız, verileri temizlediğinizden emin olun. Ayrıntılar için perlsec man sayfasına bakın.

Komut satırından çalıştırdığınızda ne olur?

Komut dosyası, komut satırından çalıştırıldığında beklediğinizi çıktı mı? Önce başlık çıktısı sonra boş bir satır mı geliyor? Unutmayın STDERRile birleştirilebilir STDOUT (örn interaktif bir oturum) bir terminal üzerinde ise ve arabelleğe nedeniyle bir karışık sırayla gösterilebilir. $|Gerçek bir değere ayarlayarak Perl'in autoflush özelliğini açın . Genellikle $|++;CGI programlarında görebilirsiniz . Ayarlandıktan sonra, her yazdırma ve yazma arabelleğe alınmak yerine hemen çıktıya gidecektir. Bunu her dosya tanıtıcısı için ayarlamalısınız. selectVarsayılan dosya tanıtıcısını şu şekilde değiştirmek için kullanın :

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

Her iki durumda da, ilk çıktı CGI başlığı ve ardından boş bir satır olmalıdır.

CGI benzeri bir ortamda komut satırından çalıştırdığınızda ne olur?

Web sunucusu ortamı genellikle komut satırı ortamınızdan çok daha sınırlıdır ve istek hakkında ek bilgi içerir. Komut dosyanız komut satırından düzgün çalışıyorsa, bir web sunucusu ortamını simüle etmeyi deneyebilirsiniz. Sorun ortaya çıkarsa, bir çevre sorununuz vardır.

Bu değişkenleri ayarlayın veya kaldırın

  • PATH
  • LD_LIBRARY_PATH
  • tüm ORACLE_*değişkenler

Bu değişkenleri ayarlayın

  • REQUEST_METHOD(ayarlandığında GET, HEADya da POSTuygun olarak)
  • SERVER_PORT (genellikle 80'e ayarlanır)
  • REMOTE_USER (korumalı erişim işleri yapıyorsanız)

CGI.pm(> 2.75) ' in son sürümleri -debugbayrağın eski (kullanışlı) davranışı almasını gerektirir , bu nedenle bunu CGI.pmiçe aktarmalarınıza eklemeniz gerekebilir .

use CGI qw(-debug)

die()Veya kullanıyor warnmusun?

Yeniden STDERRtanımlamadığınız sürece bu işlevler yazdırılır . Bir CGI başlığı da vermezler. CGI :: Carp gibi paketlerle aynı işlevselliği elde edebilirsiniz.

Tarayıcı önbelleğini temizledikten sonra ne olur?

Komut dosyanızın doğru şeyi yaptığını düşünüyorsanız ve isteği manuel olarak gerçekleştirdiğinizde doğru çıktıyı alırsanız, suçlu tarayıcı olabilir. Önbelleği temizleyin ve test sırasında önbellek boyutunu sıfıra ayarlayın. Bazı tarayıcıların gerçekten aptal olduğunu ve bunu yapmasını söyleseniz bile yeni içeriği yeniden yüklemeyeceğini unutmayın. Bu, özellikle URL yolunun aynı olduğu, ancak içeriğin değiştiği durumlarda (örneğin dinamik görüntüler) yaygındır.

Senaryo sandığınız yerde mi?

Bir komut dosyasına giden dosya sistemi yolu, komut dosyasının URL yolu ile doğrudan ilişkili olmayabilir. Bunu test etmek için kısa bir test komut dosyası yazmanız gerekse bile doğru dizine sahip olduğunuzdan emin olun. Ayrıca, doğru dosyayı değiştirdiğinizden emin misiniz? Değişikliklerinizde herhangi bir etki görmüyorsanız, farklı bir dosyayı değiştiriyor veya bir dosyayı yanlış yere yüklüyor olabilirsiniz. (Bu arada, bu tür sorunların en sık nedenini bu;)

Kullanıyor musunuz CGI.pm, yoksa bir türevi mi?

Sorununuz CGI giriş ayrıştırma ile ilgilidir ve benzeri yaygın olarak test modülü kullanmıyorsanız CGI.pm, CGI::Request, CGI::Simpleveya CGI::Litemodülü kullanmak ve hayatına devam et. CGI.pmvarcgi-lib.pleski CGI ayrıştırıcı uygulamalarından kaynaklanan girdi sorunlarını çözmenize yardımcı olabilecek uyumluluk moduna sahiptir.

Mutlak yollar kullandınız mı?

Harici komutlar system, geri işaretler veya diğer IPC tesisleri ile çalıştırıyorsanız , harici programa giden mutlak bir yol kullanmalısınız. Sadece ne çalıştırdığınızı tam olarak bilmekle kalmaz, aynı zamanda bazı güvenlik sorunlarından da kaçınırsınız. Dosyaları okumak veya yazmak için açıyorsanız, mutlak bir yol kullanın. CGI betiğinin mevcut dizin hakkında sizden farklı bir fikri olabilir. Alternatif olarak, sizi chdir()doğru yere yerleştirmek için açık bir şeyler yapabilirsiniz .

Dönüş değerlerinizi kontrol ettiniz mi?

Çoğu Perl işlevi size çalışıp çalışmadıklarını söyleyecek ve $!başarısızlık durumunda ayarlanacaktır . Dönüş değerini kontrol edip $!hata mesajlarını incelediniz mi? Kullanıp $@kullanmadığınızı kontrol ettiniz evalmi?

Perl'in hangi sürümünü kullanıyorsunuz?

Perl'in en son kararlı sürümü 5.28'dir (veya en son ne zaman düzenlendiğine bağlı olarak değildir). Daha eski bir sürüm mü kullanıyorsunuz? Perl'in farklı sürümlerinin farklı uyarı fikirleri olabilir.

Hangi web sunucusunu kullanıyorsunuz?

Aynı durumda farklı sunucular farklı davranabilir. Aynı sunucu ürünü, farklı konfigürasyonlarda farklı davranabilir. Herhangi bir yardım talebinde olabildiğince bu bilgileri ekleyin.

Sunucu belgelerini kontrol ettiniz mi?

Ciddi CGI programcıları, sunucu hakkında olabildiğince çok bilgi sahibi olmalıdır - yalnızca sunucu özellikleri ve davranışı değil, aynı zamanda yerel yapılandırma da dahil. Ticari bir ürün kullanıyorsanız, sunucunuzun belgeleri sizin için mevcut olmayabilir. Aksi takdirde, dokümantasyon sunucunuzda olmalıdır. Değilse, web'de arayın.

Arşivlerini aradınız comp.infosystems.www.authoring.cgimı?

Bu yararlı olabilir, ancak tüm iyi posterler ya öldü ya da gözden kayboldu.

Muhtemelen birisi probleminizi daha önce yaşamış ve birisi (muhtemelen ben) bu haber grubunda cevap vermiştir. Bu haber grubu altın çağını geçmiş olsa da geçmişten toplanan bilgelik bazen faydalı olabiliyor.

Kısa bir test komut dosyasıyla sorunu yeniden oluşturabilir misiniz?

Büyük sistemlerde, çok fazla şey olduğu için bir hatayı bulmak zor olabilir. Mümkün olan en kısa komut dosyasıyla sorunlu davranışı yeniden oluşturmaya çalışın. Sorunu bilmek, çözümün çoğudur. Bu kesinlikle zaman alıcı olabilir, ancak sorunu henüz bulamadınız ve seçenekleriniz tükeniyor. :)

Sinemaya gitmeye karar verdin mi?

Ciddi anlamda. Bazen problemin içine o kadar sarılabiliriz ki "algısal daralma" (tünel görüşü) geliştiririz. Bir mola vermek, bir fincan kahve içmek veya [Duke Nukem, Quake, Doom, Halo, COD] 'de bazı kötü adamları patlatmak, size soruna yeniden yaklaşmanız için gereken taze bakış açısını verebilir.

Sorunu dile getirdin mi?

Yine cidden. Bazen sorunu yüksek sesle açıklamak bizi kendi cevaplarımıza götürür. İş arkadaşlarınız dinlemediği için penguenle (peluş oyuncak) konuşun. Bununla ciddi bir hata ayıklama aracı olarak ilgileniyorsanız (ve sorunu şimdiye kadar bulamadıysanız tavsiye ederim), Bilgisayar Programlama Psikolojisi'ni de okumak isteyebilirsiniz .


4
Ekleyecek bir şeyiniz varsa cevabımı düzenlemek konusunda utanmayın.
brian d foy

Görünüşe göre CGI meta SSS bağlantısını kaldırmak isteyebilirsiniz. 5.12.1 "kararlı" olarak kabul edilir mi?
Snake Plissken

1
Neden $|=1yerine değil $|++?
reinierpost

Neden $|=1yerine $|++? Gerçekten bir fark yaratmaz ve o zaman bile $|büyülüdür.
brian d foy

2
Güzel cevap, bence bu çözümlerden bazılarının sadece sorun giderme amaçlı olması ve üretim koduna girmemesi gerektiğini belirtmekte fayda var. use strictgenellikle her zaman kullanmak iyidir, ancak özellikle kullanıyorsanız fatalsToBrowser, üretimde kullanılması tavsiye edilmeyebilir die.
vol7ron


7

Hata ayıklarken bir hata işleyici kullanıyor musunuz?

dieifadeler ve diğer ölümcül çalışma zamanı ve derleme zamanı hataları yazdırılır STDERR; bu, bulunması zor olabilir ve sitenizdeki diğer web sayfalarından gelen mesajlarla birleştirilebilir. Komut dosyanızın hatalarını ayıklarken, önemli hata mesajlarının bir şekilde tarayıcınızda görüntülenmesini sağlamak iyi bir fikirdir.

Bunu yapmanın bir yolu aramaktır

   use CGI::Carp qw(fatalsToBrowser);

senaryonuzun en üstünde. Bu çağrı bir $SIG{__DIE__}işleyici kuracaktır (bkz. Perlvar ), tarayıcınızda önemli hataları görüntüleyerek, gerekirse başına geçerli bir başlık ekleyecektir. Daha önce duyduğumdan önce kullandığım bir başka CGI hata ayıklama numarası, derleme zamanı hatalarını yakalamak için komut dosyası üzerindeki ve tesisleri ile birlikte CGI::Carpkullanmaktı :evalDATA__END__

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

Bu daha ayrıntılı tekniğin, CGI::Carpdaha fazla derleme zamanı hatası yakalayacağı için hafif bir avantajı vardır .

Güncelleme: Hiç kullanmadım, ancak CGI::DebugMikael S'nin önerdiği gibi, aynı zamanda bu amaç için çok kullanışlı ve yapılandırılabilir bir araç gibi görünüyor .


3
@Ether: <DATA>ile başlayan mevcut betiği okuyan sihirli bir dosya tanıtıcısıdır __END__. Join, liste bağlamı sağlar, bu nedenle <fh> öğe başına bir satır olacak şekilde bir dizi döndürür. Daha sonra birleştirme, onu yeniden bir araya getirir ('' ile birleştirir). Son olarak, eval.
derobert

@Ether: 2. satırı yazmanın daha okunaklı bir yolu eval join(q{}, <DATA>);
şudur

@derobert: aslında __DATA__ veri bölümünü başlatmak için kullanılan jetondur, __END__ değil (bu benim kafa karışıklığımdı).
Ether

1
@Ether: Aslında, ikisi de üst düzey senaryoda çalışıyor (perldata kılavuz sayfasına göre). Ancak DATA tercih edildiği için cevabı değiştirdim.
derobert

@derobert: belge bağlantısı için teşekkürler; __END__’ın geriye dönük uyumluluk davranışını bilmiyordum!
Ether

7

Acaba nasıl oldu da kimse PERLDB_OPTSdenen seçenekten bahsetmedi RemotePort; Her ne kadar kuşkusuz, web'de pek çok çalışma örneği yok ( perldebug'daRemotePort bahsedilmiyor bile ) - ve bunu bulmak benim için biraz sorunluydu, ama işte burada (bir Linux örneği).

Düzgün bir örnek yapmak için, önce bir CGI web sunucusunun çok basit bir simülasyonunu, tercihen tek bir komut satırı aracılığıyla yapabilen bir şeye ihtiyacım vardı. Cgis'i çalıştırmak için Basit komut satırı web sunucusunu bulduktan sonra . (perlmonks.org) , IO :: All - A Tiny Web Sunucusunu bu test için uygun buldum .

Burada /tmpdizinde çalışacağım ; CGI betiği /tmp/test.pl(aşağıda dahil edilecektir ) olacaktır. O Not IO::Allsunucusu yalnızca CGI ile aynı dizinde çalıştırılabilir dosyaları hizmet verecek, böylece chmod +x test.plburada gereklidir. Bu yüzden, olağan CGI test çalıştırmasını yapmak için, dizini /tmpterminalde olarak değiştiriyorum ve orada tek hatlı web sunucusunu çalıştırıyorum:

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

Web sunucusu komutu terminalde engelleyecek ve aksi takdirde web sunucusunu yerel olarak başlatacak (127.0.0.1 veya localhost) - daha sonra bir web tarayıcısına gidebilir ve şu adresi isteyebilirim:

http://127.0.0.1:8080/test.pl

... ve web tarayıcısına yüklenerek ve gösterilerek printyapılan e- postaları gözlemlemeliyim test.pl.


Şimdi, bu betiğin hatalarını ayıklamak için RemotePort, önce ağ üzerinde Perl hata ayıklayıcı ile etkileşime gireceğimiz bir dinleyiciye ihtiyacımız var ; komut satırı aracını kullanabiliriz netcat( ncburada gördüm: Perl 如何 uzaktan hata ayıklama? ). Bu nedenle, önce netcatdinleyiciyi bir terminalde çalıştırın - burada engelleyecek ve 7234 numaralı bağlantı noktasındaki bağlantıları bekleyecek (bu, hata ayıklama bağlantı noktamız olacaktır):

$ nc -l 7234

Sonra, istediğimiz perlile hata ayıklama modunda başlatmak için RemotePortzaman test.pl(hatta CGI modunda sunucusu üzerinden) olarak anılmıştır. Bu, Linux'ta aşağıdaki "shebang sarmalayıcı" komut dosyası kullanılarak yapılabilir - burada da olması /tmpve çalıştırılabilir hale getirilmesi gerekir :

cd /tmp

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

chmod +x perldbgcall.sh

Bu biraz aldatıcı bir şey - kabuk betiğine bakın - Shebang'ımda ortam değişkenlerini nasıl kullanabilirim? - Unix ve Linux Yığın Değişimi . Fakat, burada hile gibi görünüyor değil çatal perlkolları tercüman test.pl - biz çarptıktan sonra böylece, yok exec, bunun yerine dediğimiz perl"açıkça", ve temelde "kaynak" Bizim test.plkomut kullanarak do(bkz Ben nasıl çalıştırabilirim Perl betiği içinden Perl betiği? ).

Şimdi sahip olduğumuz perldbgcall.shiçinde /tmp- biz değiştirebilir test.plbunun (yerine her zamanki Perl tercüman) kendi shebang hattında bu yürütülebilir dosyayı ifade eder böylece, dosyayı - burada olduğu /tmp/test.pldolayısıyla modifiye:

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

Şimdi, hem test.plve yeni shebang işleyicisi, perldbgcall.shiçinde vardır /tmp; ve nc7234 numaralı bağlantı noktasındaki hata ayıklama bağlantılarını dinliyoruz - böylece sonunda başka bir terminal penceresi açabilir, dizini değiştirebilir /tmpve tek satırlık web sunucusunu (8080 numaralı bağlantı noktasındaki web bağlantılarını dinleyecek) çalıştırabiliriz:

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

Bu yapıldıktan sonra web tarayıcımıza gidebilir ve aynı adresi talep edebiliriz http://127.0.0.1:8080/test.pl. Ancak, şimdi web sunucusu betiği çalıştırmaya çalıştığında, bunu perldbgcall.shshebang aracılığıyla yapacak - bu da perluzaktan hata ayıklayıcı modunda başlayacaktır . Bu nedenle, komut dosyası yürütme duraklayacak ve böylece web tarayıcısı kilitlenerek verileri bekler. Artık netcatterminale geçebiliriz ve aşina olduğumuz Perl hata ayıklayıcı metnini görmeliyiz - ancak çıktı 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>

Parçacıkta gösterildiği gibi, artık temelde ncbir "terminal" olarak kullanıyoruz - böylece r"çalıştır" için yazabiliriz (ve Enter) - ve komut dosyası kesme noktası ifadesini çalıştıracak (ayrıca bkz Perl'de, $ arasındaki fark nedir? DB :: single = 1 ve 2? ), Tekrar durmadan önce (bu noktada tarayıcının yine de kilitleneceğini unutmayın).

Yani, şimdi biz, geri kalanında adımını söyleyebiliriz test.plaracılığıyla, ncterminali:

....
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>

... ancak, bu noktada da tarayıcı verileri kilitler ve bekler. Sadece hata ayıklayıcıdan çıktıktan sonra q:

  DB<1> q
$

... tarayıcı kilitlemeyi durdurur mu - ve son olarak şu (tam) çıktısını görüntüler test.pl:

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

Elbette, bu tür bir hata ayıklama işlemi web sunucusunu çalıştırmadan da yapılabilir - ancak, buradaki güzel şey, web sunucusuna hiç dokunmamamız; yürütmeyi bir web tarayıcısından "yerel olarak" (CGI için) tetikleriz - ve CGI betiğinin kendisinde gerekli olan tek değişiklik, shebang değişikliğidir (ve tabii ki, aynı dosyada çalıştırılabilir dosya olarak shebang sarmalayıcı betiğinin varlığı) dizin).

Pekala, umarım bu birisine yardımcı olur - Kendim yazmak yerine, buna tökezlemiş olmayı çok isterdim :)
Şerefe!


5

Benim için log4perl kullanıyorum . Oldukça kullanışlı ve kolaydır.

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");

1

Dürüst olmak gerekirse, bu yazının üzerindeki tüm eğlenceli şeyleri yapabilirsiniz. Yine de, bulduğum en basit ve en proaktif çözüm sadece "yazdırmaktı".

Örneğin: (Normal kod)

`$somecommand`;

Gerçekten yapmasını istediğim şeyi yapıp yapmadığını görmek için: (Sorun giderme)

print "$somecommand";

1

Perl betiğini komut satırından çalıştırdığınızda, Perl'in size her zaman hatanın hangi satırda oluştuğunu söyleyeceğini de belirtmekte fayda var. (Örneğin bir SSH Oturumu)

Her şey başarısız olursa genellikle bunu yapacağım. Sunucuya SSH yapacağım ve Perl betiğini manuel olarak çalıştıracağım. Örneğin:

% perl myscript.cgi 

Bir sorun varsa Perl size anlatacaktır. Bu hata ayıklama yöntemi, dosya izni ile ilgili sorunları veya web tarayıcısı veya web sunucusu sorunlarını ortadan kaldırır.


Perl size her zaman bir hatanın oluştuğu satır numarasını söylemez. Yanlış bir şey olduğunu anladığı satır numarasını size söyler. Hata büyük olasılıkla zaten olmuştur.
brian d foy

0

Aşağıdaki komutu kullanarak perl cgi komut dosyasını terminalde çalıştırabilirsiniz.

 $ perl filename.cgi

Kodu yorumlar ve sonucu HTML kodu ile sağlar. Varsa hatayı bildirir.


1
Üzgünüz, $ perl -c filename.cgi komutu kodun sözdizimini doğrular ve varsa hatayı bildirir. Cgi'nin html kodunu sağlamaz.
D.Karthikeyan

Çağırmak perl -c filenamegerçekten sadece sözdizimini kontrol edecektir. Ancak perl filenameHTML çıktısını yazdırır. 500 CGI hatası olmayacağının garantisi yoktur, ancak bu iyi bir ilk testtir.
Nagev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.