मैं अपनी पर्ल सीजीआई स्क्रिप्ट का कैसे निवारण कर सकता हूं?


100

मेरे पास एक पर्ल स्क्रिप्ट है जो काम नहीं कर रही है और मुझे नहीं पता कि समस्या को कैसे कम किया जाए। मैं क्या कर सकता हूँ?


नोट: मैं प्रश्न जोड़ रहा हूं क्योंकि मैं वास्तव में स्टैकओवरफ्लो में अपना बहुत लंबा जवाब जोड़ना चाहता हूं। मैं अन्य उत्तरों में इसे बाहरी रूप से जोड़ता रहता हूं और यह यहां रहने के योग्य है। अगर आपको कुछ जोड़ना है तो मेरे उत्तर को संपादित करने में शर्म न करें।


5
@Evan - मेरी बात बस यह है कि यह अभी भी रूप में गैर-सीडब्ल्यू है है संपादन योग्य - यदि आपके पास पर्याप्त कर्म है; 100 सीडब्ल्यू के लिए, 2k अन्यथा। तो अब आपके पास 2060 हैं जो आपको गैर-सीडब्ल्यू पदों को संपादित करने में सक्षम होना चाहिए।
मार्क Gravell

1
@ इवान, जादू बिंदु दाहिने हाथ के स्तंभ में टूलटिप्स में सूचीबद्ध हैं: stackoverflow.com/privileges
cjm

यदि आपका वेब ब्राउज़र लाइन शोर दिखा रहा है, तो हो सकता है कि वह पर्ल स्क्रिप्ट को प्रिंट कर रहा हो। उस स्थिति में, stackoverflow.com/questions/2621161/…
एंड्रयू ग्रिम

जवाबों:


129

यह उत्तर पर्ल सीजीआई लिपियों के साथ समस्याओं के माध्यम से काम करने के लिए एक सामान्य रूपरेखा के रूप में अभिप्रेत है और मूल रूप से पेरलोनक्स पर समस्या निवारण पर्ल सीजीआई लिपियों के रूप में दिखाई दिया । यह हर उस समस्या के लिए एक पूर्ण मार्गदर्शिका नहीं है, जिसका सामना आप कर सकते हैं, न ही बग स्क्वाशिंग पर एक ट्यूटोरियल। यह सिर्फ बीस (प्लस!) वर्षों के लिए सीजीआई लिपियों को डिबग करने के मेरे अनुभव की परिणति है। इस पृष्ठ में कई अलग-अलग घर हैं, और मुझे लगता है कि यह भूल गया है कि यह मौजूद है, इसलिए मैं इसे StackOverflow में जोड़ रहा हूं। आप मुझे bdfoy@cpan.org पर कोई भी टिप्पणी या सुझाव भेज सकते हैं। यह सामुदायिक विकि भी है, लेकिन बहुत अधिक पागल नहीं हैं। :)


क्या आप समस्याओं को खोजने में मदद करने के लिए पर्ल की निर्मित सुविधाओं का उपयोग कर रहे हैं?

पर्ल को चेतावनी दें कि आप अपने कोड के संदिग्ध भागों के बारे में चेतावनी दें। आप इसे कमांड लाइन से -wस्विच के साथ कर सकते हैं, ताकि आपको कोई कोड बदलने या हर फाइल में एक प्रागं जोड़ने की जरूरत न हो:

 % perl -w program.pl

हालाँकि, आपको warningsअपनी सभी फ़ाइलों के लिए प्रज्ञा को जोड़कर अपने आप को हमेशा संदिग्ध कोड को साफ़ करने के लिए मजबूर करना चाहिए :

 use warnings;

यदि आपको लघु चेतावनी संदेश से अधिक जानकारी की आवश्यकता है, तो अधिक जानकारी diagnosticsप्राप्त करने के लिए प्रागमा का उपयोग करें , या पेरीडिएग प्रलेखन में देखें:

 use diagnostics;

क्या आपने पहले वैध सीजीआई हेडर का उत्पादन किया था?

सर्वर CGI स्क्रिप्ट से CGI हेडर बनने के लिए पहले आउटपुट की उम्मीद कर रहा है। आमतौर पर है कि के रूप में सरल रूप में हो सकता है print "Content-type: text/plain\n\n";या साथ CGI.pm , और उसके डेरिवेटिव print header()। कुछ सर्वर STDERRमानक आउटपुट (ऑन STDOUT) से पहले त्रुटि आउटपुट (ऑन ) को दिखाने में संवेदनशील होते हैं ।

ब्राउज़र में त्रुटियाँ भेजने का प्रयास करें

इस लाइन को जोड़ें

 use CGI::Carp 'fatalsToBrowser';

अपनी स्क्रिप्ट के लिए। यह ब्राउज़र विंडो में संकलन त्रुटियों को भी भेजता है। उत्पादन वातावरण में जाने से पहले इसे निकालना सुनिश्चित करें, क्योंकि अतिरिक्त जानकारी सुरक्षा जोखिम हो सकती है।

त्रुटि लॉग ने क्या कहा?

सर्वर त्रुटि लॉग (या उन्हें कम से कम) रखना चाहिए। सर्वर से त्रुटि आउटपुट और आपकी स्क्रिप्ट से वहाँ दिखाना चाहिए। त्रुटि लॉग ढूंढें और देखें कि यह क्या कहता है। लॉग फ़ाइलों के लिए एक मानक स्थान नहीं है। उनके स्थान के लिए सर्वर कॉन्फ़िगरेशन में देखें, या सर्वर व्यवस्थापक से पूछें। आप अपनी लॉग फाइल रखने के लिए CGI :: Carp जैसे टूल का भी उपयोग कर सकते हैं ।

स्क्रिप्ट की अनुमतियां क्या हैं?

यदि आप "अनुमति अस्वीकृत" या "विधि लागू नहीं की गई" जैसी त्रुटियां देखते हैं, तो संभवतः इसका मतलब है कि वेब सर्वर उपयोगकर्ता द्वारा आपकी स्क्रिप्ट पठनीय और निष्पादन योग्य नहीं है। यूनिक्स के स्वादों पर, मोड को 755 में बदलने की सिफारिश की गई है chmod 755 filename:। 777 में कोई मोड सेट न करें!

क्या आप उपयोग कर रहे हैं use strict?

याद रखें कि जब आप पहली बार उनका उपयोग करते हैं, तो पर्ल स्वचालित रूप से चर बनाता है। यह एक विशेषता है, लेकिन कभी-कभी बग का कारण बन सकता है यदि आप एक चर नाम को गलत करते हैं। प्रज्ञा use strictआपको उन प्रकार की त्रुटियों को खोजने में मदद करेगी। यह तब तक कष्टप्रद है जब तक आपको इसकी आदत न हो जाए, लेकिन थोड़ी देर बाद आपकी प्रोग्रामिंग में काफी सुधार होगा और आप अलग-अलग गलतियाँ करने के लिए स्वतंत्र होंगे।

स्क्रिप्ट संकलित करता है?

आप -c स्विच का उपयोग करके संकलन त्रुटियों की जांच कर सकते हैं । रिपोर्ट की गई पहली त्रुटियों पर ध्यान दें। कुल्ला, दोहराना। यदि आपको वास्तव में अजीब त्रुटियां हो रही हैं, तो यह सुनिश्चित करने के लिए जांचें कि आपकी स्क्रिप्ट में सही लाइन एंडिंग्स हैं। यदि आप बाइनरी मोड में एफ़टीपी, सीवीएस से चेकआउट, या कुछ और जो लाइन एंड ट्रांसलेशन को हैंडल नहीं करते हैं, तो वेब सर्वर आपकी स्क्रिप्ट को एक बड़ी लाइन के रूप में देख सकता है। ASCII मोड में पर्ल स्क्रिप्ट ट्रांसफर करें।

क्या स्क्रिप्ट असुरक्षित निर्भरता के बारे में शिकायत कर रही है?

यदि आपकी स्क्रिप्ट असुरक्षित निर्भरता के बारे में शिकायत करती है, तो आप शायद -Tस्विच का उपयोग दागी मोड को चालू करने के लिए कर रहे हैं , जो एक अच्छी बात है क्योंकि यह आपके पास अनियंत्रित डेटा को शेल में भेज रहा है। यदि यह शिकायत कर रहा है कि यह अधिक सुरक्षित स्क्रिप्ट लिखने में हमारी मदद करने के लिए अपना काम कर रहा है। कार्यक्रम (अर्थात पर्यावरण) के बाहर से उत्पन्न कोई भी डेटा दागी माना जाता है। पर्यावरण चर जैसे कि PATHऔर LD_LIBRARY_PATH विशेष रूप से परेशान करने वाले हैं। आपको इन्हें एक सुरक्षित मूल्य पर सेट करना होगा या उन्हें पूरी तरह से अनसेट करना होगा, जैसा कि मैं सुझाता हूं। आपको वैसे भी निरपेक्ष रास्तों का उपयोग करना चाहिए। यदि दागी जाँच किसी और चीज़ के बारे में शिकायत करती है, तो सुनिश्चित करें कि आपने डेटा को प्राप्त नहीं किया है। देखें perlsec जानकारी के लिए आदमी पेज।

जब आप इसे कमांड लाइन से चलाते हैं तो क्या होता है?

क्या कमांड लाइन से चलने पर स्क्रिप्ट आउटपुट होता है? क्या हेडर आउटपुट पहले है, उसके बाद एक खाली लाइन है? याद रखें कि यदि आप एक टर्मिनल पर हैं (जैसे कि एक इंटरैक्टिव सत्र), और बफ़रिंग के कारण एक जंबल्ड क्रम में दिखाई STDERRदे सकता है तो विलय हो सकता है STDOUT$|सच्चे मूल्य पर सेट करके पर्ल के ऑटोफ्लश फीचर को चालू करें । आमतौर पर आप $|++;CGI कार्यक्रमों में देख सकते हैं । एक बार सेट हो जाने पर, हर प्रिंट और राइट बफ़र्ड होने के बजाय तुरंत आउटपुट पर जाएगा। आपको इसे प्रत्येक फ़ाइलहैंडल के लिए सेट करना होगा। selectडिफ़ॉल्ट फ़ाइलहैंडल को बदलने के लिए उपयोग करें , जैसे:

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

किसी भी तरह से, पहली बात आउटपुट सीजीआई हेडर होना चाहिए और उसके बाद एक खाली लाइन।

क्या होता है जब आप इसे कमांड लाइन से CGI जैसे पर्यावरण से चलाते हैं?

वेब सर्वर वातावरण आमतौर पर आपके कमांड लाइन वातावरण की तुलना में बहुत अधिक सीमित है, और अनुरोध के बारे में अतिरिक्त जानकारी है। यदि आपकी स्क्रिप्ट कमांड लाइन से ठीक चलती है, तो आप एक वेब सर्वर वातावरण का अनुकरण करने का प्रयास कर सकते हैं। यदि समस्या दिखाई देती है, तो आपके पास एक पर्यावरण समस्या है।

इन चरों को परेशान या हटाएं

  • PATH
  • LD_LIBRARY_PATH
  • सभी ORACLE_*चर

ये चर सेट करें

  • REQUEST_METHOD(करने के लिए सेट GET, HEADया POSTउचित रूप में)
  • SERVER_PORT (आमतौर पर 80 पर सेट)
  • REMOTE_USER (यदि आप संरक्षित एक्सेस सामान कर रहे हैं)

CGI.pm(> 2.75) के हाल के संस्करणों को -debugपुराने (उपयोगी) व्यवहार को प्राप्त करने के लिए ध्वज की आवश्यकता है, इसलिए आपको इसे अपने CGI.pmआयातों में जोड़ना पड़ सकता है ।

use CGI qw(-debug)

आप उपयोग कर रहे हैं die()या warn?

STDERRजब तक आप उन्हें नए सिरे से परिभाषित नहीं करते हैं तब तक वे कार्य प्रिंट होते रहते हैं वे या तो CGI हेडर का उत्पादन नहीं करते हैं। आप CGI :: कार्प जैसे पैकेज के साथ समान कार्यक्षमता प्राप्त कर सकते हैं

ब्राउज़र कैश साफ़ करने के बाद क्या होता है?

अगर आपको लगता है कि आपकी स्क्रिप्ट सही काम कर रही है, और जब आप मैन्युअल रूप से अनुरोध करते हैं कि आपको सही आउटपुट मिले, तो ब्राउज़र अपराधी हो सकता है। कैश साफ़ करें और परीक्षण करते समय कैश आकार शून्य पर सेट करें। याद रखें कि कुछ ब्राउज़र वास्तव में बेवकूफ हैं और वास्तव में नई सामग्री को फिर से लोड नहीं करेंगे, भले ही आप ऐसा करने के लिए कहें। यह उन मामलों में विशेष रूप से प्रचलित है जहां URL पथ समान है, लेकिन सामग्री बदलती है (जैसे गतिशील छवियां)।

क्या आपको लगता है कि स्क्रिप्ट है?

स्क्रिप्ट के लिए फ़ाइल सिस्टम पथ आवश्यक नहीं है कि वह सीधे स्क्रिप्ट के URL पथ से संबंधित हो। सुनिश्चित करें कि आपके पास सही निर्देशिका है, भले ही आपको इसे परीक्षण करने के लिए एक छोटी परीक्षण स्क्रिप्ट लिखनी पड़े। इसके अलावा, क्या आप सुनिश्चित हैं कि आप सही फ़ाइल को संशोधित कर रहे हैं? यदि आपको अपने परिवर्तनों के साथ कोई प्रभाव दिखाई नहीं देता है, तो आप किसी भिन्न फ़ाइल को संशोधित कर सकते हैं, या किसी फ़ाइल को गलत स्थान पर अपलोड कर सकते हैं। (यह, वैसे, मेरी ऐसी परेशानी का सबसे लगातार कारण है;)

क्या आप इसका उपयोग कर रहे हैं CGI.pmया इसका व्युत्पन्न कर रहे हैं ?

यदि आपकी समस्या CGI इनपुट पार्स करने से संबंधित है और आप व्यापक रूप से परीक्षण किए गए मॉड्यूल का उपयोग नहीं कर रहे हैं CGI.pm, जैसे CGI::Request, CGI::Simpleया CGI::Lite, मॉड्यूल का उपयोग करें और जीवन के साथ प्राप्त करें। CGI.pmएक cgi-lib.plसंगतता मोड है जो पुराने CGI पार्सर कार्यान्वयन के कारण इनपुट समस्याओं को हल करने में आपकी सहायता कर सकता है।

क्या आपने निरपेक्ष रास्तों का उपयोग किया?

यदि आप बाहरी कमांड्स system, बैक टिक्स, या अन्य IPC सुविधाओं के साथ चल रहे हैं , तो आपको बाहरी प्रोग्राम के लिए एक निरपेक्ष पथ का उपयोग करना चाहिए। न केवल आपको पता है कि आप क्या चला रहे हैं, बल्कि आप कुछ सुरक्षा समस्याओं से भी बचते हैं। यदि आप या तो पढ़ने या लिखने के लिए फाइलें खोल रहे हैं, तो एक पूर्ण पथ का उपयोग करें। CGI स्क्रिप्ट में आपकी वर्तमान निर्देशिका के बारे में एक अलग विचार हो सकता है। वैकल्पिक रूप से, आप chdir()सही जगह पर रखने के लिए एक स्पष्ट कर सकते हैं ।

क्या आपने अपने रिटर्न मूल्यों की जांच की?

अधिकांश पर्ल फ़ंक्शन आपको बताएंगे कि उन्होंने काम किया या नहीं और $!विफलता पर सेट होगा । क्या आपने रिटर्न वैल्यू की जांच की और $!त्रुटि संदेशों की जांच की ? $@यदि आप उपयोग कर रहे थे तो क्या आपने जाँच की थी eval?

पर्ल का कौन सा संस्करण आप उपयोग कर रहे हैं?

पर्ल का नवीनतम स्थिर संस्करण 5.28 है (या नहीं, यह इस बात पर निर्भर करता है कि यह आखिरी बार कब संपादित किया गया था)। क्या आप पुराने संस्करण का उपयोग कर रहे हैं? पर्ल के विभिन्न संस्करणों में चेतावनी के विभिन्न विचार हो सकते हैं।

आप किस वेब सर्वर का उपयोग कर रहे हैं?

अलग-अलग सर्वर एक ही स्थिति में अलग-अलग कार्य कर सकते हैं। एक ही सर्वर उत्पाद अलग-अलग कॉन्फ़िगरेशन के साथ अलग-अलग कार्य कर सकता है। मदद के लिए किसी भी अनुरोध में इस जानकारी को अधिक से अधिक शामिल करें।

क्या आपने सर्वर प्रलेखन की जांच की?

गंभीर सीजीआई प्रोग्रामर को सर्वर के बारे में जितना संभव हो पता होना चाहिए - जिसमें न केवल सर्वर की विशेषताएं और व्यवहार, बल्कि स्थानीय कॉन्फ़िगरेशन भी शामिल है। यदि आप किसी व्यावसायिक उत्पाद का उपयोग कर रहे हैं तो आपके सर्वर के लिए दस्तावेज़ आपके लिए उपलब्ध नहीं हो सकते हैं। अन्यथा, दस्तावेज़ आपके सर्वर पर होना चाहिए। यदि ऐसा नहीं है, तो वेब पर इसके लिए देखें।

आप के अभिलेखागार की खोज की comp.infosystems.www.authoring.cgi?

यह उपयोगी होने के लिए उपयोग होता है लेकिन सभी अच्छे पोस्टर या तो मर गए हैं या भटक गए हैं।

यह संभावना है कि किसी को आपकी समस्या पहले हो गई है, और किसी ने (संभवतः मुझे) इस समाचार समूह में इसका उत्तर दिया है। हालाँकि इस समाचार समूह ने अपना दिन बिताया है, लेकिन अतीत से एकत्र ज्ञान कभी-कभी उपयोगी हो सकता है।

क्या आप लघु परीक्षण स्क्रिप्ट के साथ समस्या को पुन: उत्पन्न कर सकते हैं?

बड़े सिस्टम में, बग को ट्रैक करना मुश्किल हो सकता है क्योंकि बहुत सारी चीजें हो रही हैं। कम से कम संभव स्क्रिप्ट के साथ समस्या व्यवहार को पुन: पेश करने का प्रयास करें। समस्या को जानना सबसे ज्यादा ठीक है। यह निश्चित रूप से समय लेने वाला हो सकता है, लेकिन आपको अभी तक समस्या नहीं मिली है और आप विकल्पों से बाहर चल रहे हैं। :)

क्या आपने फिल्म देखने का फैसला किया?

गंभीरता से। कभी-कभी हम समस्या में इतने अधिक लिपट जाते हैं कि हम "अवधारणात्मक संकीर्णता" (सुरंग दृष्टि) विकसित कर लेते हैं। ब्रेक लेना, एक कप कॉफी लेना, या [ड्यूक नुकेम, क्वेक, डूम, हेलो, सीओडी] में कुछ बुरे लोगों को नष्ट करना आपको ताजा दृष्टिकोण दे सकता है जिसे आपको समस्या को फिर से समझने की आवश्यकता है।

क्या आपने समस्या को मुखर किया है?

गंभीरता से फिर से। कभी-कभी समस्या की व्याख्या करने से हमें अपने स्वयं के उत्तरों की ओर ले जाता है। पेंगुइन (आलीशान खिलौना) से बात करें क्योंकि आपके सहकर्मी सुन नहीं रहे हैं। यदि आप इसमें एक गंभीर डिबगिंग टूल के रूप में रुचि रखते हैं (और मैं आपको यह सलाह देता हूं कि यदि आपको अब तक समस्या नहीं मिली है), तो आप कंप्यूटर के मनोविज्ञान को पढ़ना भी पसंद कर सकते हैं ।


4
यदि आपको कुछ जोड़ना है तो मेरे उत्तर को संपादित करने में संकोच न करें।
ब्रायन डी फ़ो

लगता है कि आप CGI मेटा FAQ के लिंक को हटाना चाह सकते हैं। क्या 5.12.1 को "स्थिर" माना जाता है?
सांप प्लिस्केन

1
$|=1इसके बजाय क्यों नहीं $|++?
रीयरियरपोस्ट

$|=1इसके बजाय क्यों $|++? यह वास्तव में फर्क नहीं करता है, और फिर भी, $|जादुई है।
ब्रायन डी फॉय

2
अच्छा जवाब, मुझे लगता है कि यह उल्लेखनीय है कि इनमें से कुछ समाधान विशुद्ध रूप से समस्या निवारण के लिए होने चाहिए और उत्पादन कोड में नहीं डाले जाने चाहिए। use strictआम तौर पर हर समय उपयोग करना अच्छा होता है, जबकि fatalsToBrowserउत्पादन में उपयोग की सलाह नहीं दी जा सकती है, खासकर यदि आप उपयोग कर रहे हैं die
vol7ron


7

क्या आप डिबगिंग करते समय एक त्रुटि हैंडलर का उपयोग कर रहे हैं?

dieस्टेटमेंट और अन्य घातक रन-टाइम और कंपाइल-टाइम त्रुटियां मुद्रित हो जाती हैं STDERR, जिन्हें खोजना मुश्किल हो सकता है और आपकी साइट पर अन्य वेब पेजों के संदेशों के साथ भ्रमित हो सकता है। जब आप अपनी स्क्रिप्ट को डीबग कर रहे हों, तो अपने ब्राउज़र में किसी भी तरह प्रदर्शित होने के लिए घातक त्रुटि संदेश प्राप्त करना एक अच्छा विचार है।

ऐसा करने का एक तरीका कॉल करना है

   use CGI::Carp qw(fatalsToBrowser);

आपकी स्क्रिप्ट के शीर्ष पर। वह कॉल आपके ब्राउज़र में एक $SIG{__DIE__}हैंडलर ( perlvar देखें ) घातक त्रुटियों को स्थापित करेगा , यदि आवश्यक हो तो इसे एक वैध हेडर के साथ प्रस्तुत करना। एक और CGI डिबगिंग ट्रिक जो मैंने पहले कभी सुनी CGI::Carpथी, संकलन समय को पकड़ने के लिए स्क्रिप्ट पर सुविधाओं और सुविधाओं के evalसाथ उपयोग करने के लिए थी :DATA__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

इस अधिक वर्बोज़ तकनीक का इसमें थोड़ा फायदा CGI::Carpहै कि यह अधिक संकलन-समय की त्रुटियों को पकड़ लेगी।

अद्यतन: मैंने इसका कभी उपयोग नहीं किया है, लेकिन ऐसा लगता है CGI::Debug, जैसा कि मिकेल एस ने सुझाव दिया है, इस उद्देश्य के लिए भी एक बहुत ही उपयोगी और विन्यास योग्य उपकरण है।


3
@ इथर: <DATA>एक मैजिक फाइलहैंडल है, जो चालू स्क्रिप्ट को पढ़ता है __END__। सम्मिलित हों यह सूची संदर्भ प्रदान कर रहा है, इसलिए <fh> एक सरणी, प्रति आइटम एक पंक्ति देता है। फिर जुड़ने के लिए इसे वापस एक साथ रखें (इसे '' के साथ जोड़कर)। अंत में, eval।
derobert

@Ether: लिखने लाइन के लिए एक और अधिक पठनीय रास्ता 2 होगा:eval join(q{}, <DATA>);
derobert

@derobert: वास्तव में, __DATA__ डेटा खंड को शुरू करने के लिए उपयोग किया जाने वाला टोकन है, न कि __END__ (मुझे लगता है कि यह मेरा भ्रम था)।
ईथर

1
@ अन्य: ठीक है, वास्तव में, वे दोनों शीर्ष-स्तर की स्क्रिप्ट में काम करते हैं (प्रति व्यक्ति मेनपेज के अनुसार)। लेकिन जब से डेटा को प्राथमिकता दी जाती है, मैंने उत्तर बदल दिया है।
derobert

@derobert: डॉक्टर लिंक के लिए धन्यवाद; मैं __END__ के पश्चगामी संगतता व्यवहार के बारे में नहीं जानता था!
ईथर

7

मुझे आश्चर्य है कि कैसे किसी ने PERLDB_OPTSबुलाया विकल्प का उल्लेख नहीं किया RemotePort; हालांकि बेशक, वहाँ वेब पर कई काम कर रहे उदाहरण (नहीं कर रहे हैं RemotePortयहां तक कि में उल्लेख नहीं है perldebug ) - और यह थोड़े समस्याग्रस्त था मुझे इस एक साथ आने के लिए के लिए, लेकिन यहाँ यह जाता है (यह एक लिनक्स उदाहरण है)।

एक उचित उदाहरण करने के लिए, पहले मुझे एक सीजीआई वेब सर्वर का एक बहुत ही सरल सिमुलेशन, अधिमानतः एक कमांड लाइन के माध्यम से करना चाहिए। Cgis चलाने के लिए सरल कमांड लाइन वेब सर्वर खोजने के बाद (perlmonks.org) , मैंने इस परीक्षण के लिए IO :: All - A टिनी वेब सर्वर को लागू किया।

यहाँ, मैं /tmpनिर्देशिका में काम करूँगा ; CGI स्क्रिप्ट होगी /tmp/test.pl(नीचे शामिल)। ध्यान दें कि IO::Allसर्वर केवल निष्पादन योग्य फ़ाइलों को उसी निर्देशिका में CGI के रूप में कार्य करेगा, इसलिए chmod +x test.plयहां इसकी आवश्यकता है। इसलिए, सामान्य CGI टेस्ट रन करने के लिए, मैं /tmpटर्मिनल में डायरेक्टरी को बदलता हूं , और वहां वन-लाइनर वेब सर्वर चलाता हूं :

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

वेबसर्वर कमांड टर्मिनल में ब्लॉक हो जाएगा, और अन्यथा स्थानीय रूप से वेब सर्वर (127.0.0.1 या localhost) पर शुरू होगा - बाद में, मैं एक वेब ब्राउज़र पर जा सकता हूं, और इस पते का अनुरोध कर सकता हूं:

http://127.0.0.1:8080/test.pl

... और मुझे वेब ब्राउजर में लोड printकिया test.plजा रहा है और दिखाया जाना चाहिए ।


अब, इस स्क्रिप्ट को डीबग करने के लिए RemotePort, पहले हमें नेटवर्क पर एक श्रोता की आवश्यकता है , जिसके माध्यम से हम पर्ल डिबगर के साथ बातचीत करेंगे; हम कमांड लाइन टूल का उपयोग कर सकते हैं netcat( nc, देखा कि यहां: पर्ल the रिमोट डिबग? )। इसलिए, पहले netcatएक टर्मिनल में श्रोता को चलाएं - जहां यह ब्लॉक करेगा और पोर्ट 7234 पर कनेक्शन की प्रतीक्षा करेगा (जो हमारा डिबेट पोर्ट होगा):

$ nc -l 7234

फिर, हम perlडिबग मोड में शुरू करना चाहते हैं RemotePort, जब test.plबुलाया गया है (यहां तक ​​कि सीजीआई मोड में, सर्वर के माध्यम से)। यह लिनक्स में, निम्नलिखित "मामला आवरण" स्क्रिप्ट का उपयोग किया जा सकता है - जो यहाँ भी होने की जरूरत है /tmp, और चाहिए निष्पादन योग्य बनाया जा:

cd /tmp

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

chmod +x perldbgcall.sh

यह एक तरह की मुश्किल बात है - शेल स्क्रिप्ट देखें - मैं अपने शेबंग में पर्यावरण चर का उपयोग कैसे कर सकता हूं? - यूनिक्स और लिनक्स स्टैक एक्सचेंज । लेकिन, यहाँ ट्रिक इंटरप्रेटर को कांटे की तरह नहीं लगती है perlजो हैंडल करता है test.pl - इसलिए एक बार जब हम इसे मारते हैं, तो हम नहीं करते हैं exec, लेकिन इसके बजाय हम perl"स्पष्ट रूप से" कहते हैं, और मूल रूप से "स्रोत" हमारी test.plस्क्रिप्ट का उपयोग करते हैं do(देखें कि मैं कैसे चलाऊं पर्ल स्क्रिप्ट एक पर्ल स्क्रिप्ट के भीतर से? )।

अब जब हमारे पास perldbgcall.shहै /tmp- हम test.plफ़ाइल को बदल सकते हैं , ताकि यह इस निष्पादन योग्य फ़ाइल को इसकी शेबंग लाइन (सामान्य पर्ल दुभाषिया के बजाय) पर संदर्भित करे - यहाँ /tmp/test.plइस प्रकार संशोधित किया गया है:

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

अब, दोनों test.plऔर इसके नए हेबैंग हैंडलर, perldbgcall.shमें हैं /tmp; और हम ncपोर्ट 7234 पर डिबग कनेक्शन के लिए सुन रहे हैं - इसलिए हम अंत में एक और टर्मिनल विंडो खोल सकते हैं, निर्देशिका को बदल सकते हैं /tmpऔर वन-लाइनर वेबसर्वर चला सकते हैं (जो पोर्ट 8080 पर वेब कनेक्शन के लिए सुनेंगे):

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

ऐसा करने के बाद, हम, हमारी वेब ब्राउज़र पर जाएं, और एक ही पते का अनुरोध कर सकते http://127.0.0.1:8080/test.pl। हालांकि, अब जब वेबसर्वर स्क्रिप्ट को निष्पादित करने की कोशिश करता है, तो वह perldbgcall.shशेबंग के माध्यम से ऐसा करेगा - जो perlदूरस्थ डिबगर मोड में शुरू होगा । इस प्रकार, स्क्रिप्ट निष्पादन रुक जाएगा - और इसलिए वेब ब्राउज़र लॉक हो जाएगा, डेटा की प्रतीक्षा कर रहा है। हम अब netcatटर्मिनल पर जा सकते हैं , और हमें परिचित पर्ल डिबगर टेक्स्ट को देखना चाहिए - हालाँकि, इसके माध्यम से आउटपुट 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>

जैसा कि स्निपेट दिखाता है, अब हम मूल ncरूप से एक "टर्मिनल" के रूप में उपयोग करते हैं - इसलिए हम r"रन" के लिए टाइप (और दर्ज) कर सकते हैं - और स्क्रिप्ट रनपॉइंट स्टेटमेंट को करेगा (यह भी देखें पर्ल में, $ का अंतर क्या है DB :: सिंगल = 1 और 2? ), फिर से रोकने से पहले (उस बिंदु पर ध्यान दें, ब्राउज़र अभी भी लॉक होगा)।

तो, अब, हम, टर्मिनल के test.plमाध्यम से , शेष के माध्यम से कह सकते हैं nc:

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

... हालाँकि, इस बिंदु पर भी, ब्राउज़र डेटा के लिए लॉक और प्रतीक्षा करता है। हम केवल डिबगर से बाहर निकलने के बाद q:

  DB<1> q
$

... क्या ब्राउज़र लॉक करना बंद कर देता है - और अंत में (पूर्ण) आउटपुट दिखाता है test.pl:

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

बेशक, इस तरह का डिबग वेब सर्वर को चलाने के बिना भी किया जा सकता है - हालांकि, यहां सबसे साफ बात यह है कि हम वेब सर्वर को बिल्कुल भी नहीं छूते हैं; हम निष्पादन को "मूल रूप से" (CGI के लिए) एक वेब ब्राउज़र से ट्रिगर करते हैं - और केवल CGI स्क्रिप्ट में आवश्यक परिवर्तन, हींग का परिवर्तन है (और ज़ाहिर है, उसी में निष्पादन योग्य फ़ाइल के रूप में शेबंग रैपर स्क्रिप्ट की उपस्थिति, निर्देशिका)।

खैर, उम्मीद है कि यह किसी की मदद करता है - मुझे यकीन है कि इस पर खुद को :)
चीयर्स लिखने के बजाय इस पर ठोकर खाई होगी !


5

मेरे लिए, मैं log4perl का उपयोग करता हूं । यह काफी उपयोगी और आसान है।

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

ईमानदारी से आप इस पोस्ट के ऊपर सभी मजेदार सामान कर सकते हैं। ALTHOUGH, सबसे सरल और सबसे सक्रिय समाधान जो मुझे मिला वह सिर्फ "इसे प्रिंट करना" था।

उदाहरण में: (सामान्य कोड)

`$somecommand`;

यह देखने के लिए कि क्या मैं वास्तव में ऐसा करना चाहता हूं: (परेशानी की शूटिंग)

print "$somecommand";

1

यह भी उल्लेखनीय होगा कि पर्ल हमेशा आपको बताएगा कि कमांड लाइन से पर्ल स्क्रिप्ट निष्पादित करते समय त्रुटि किस लाइन में होती है। (उदाहरण के लिए एक एसएसएच सत्र)

मैं आमतौर पर यह करूँगा अगर बाकी सब विफल हो जाता है। मैं सर्वर में एसएसएच करूंगा और मैन्युअल रूप से पर्ल स्क्रिप्ट निष्पादित करूंगा। उदाहरण के लिए:

% perl myscript.cgi 

अगर कोई समस्या है तो पर्ल आपको इसके बारे में बताएगा। यह डिबगिंग विधि किसी भी फ़ाइल अनुमति से संबंधित मुद्दों या वेब ब्राउज़र या वेब सर्वर मुद्दों के साथ दूर करती है।


पर्ल हमेशा आपको लाइन नंबर नहीं बताता है जहां कोई त्रुटि होती है। यह आपको लाइन नंबर बताता है, जहां यह पता चलता है कि कुछ गड़बड़ है। त्रुटि संभावना पहले से ही हुई है।
ब्रायन डी फ़ो

0

आप नीचे दिए गए आदेश का उपयोग करके टर्मिनल में perl cgi-script चला सकते हैं

 $ perl filename.cgi

यह कोड की व्याख्या करता है और HTML कोड के साथ परिणाम प्रदान करता है। यह त्रुटि की सूचना देगा यदि कोई हो।


1
क्षमा करें, आदेश $ perl -c filename.cgi कोड के सिंटैक्स को मान्य करता है और यदि कोई हो तो त्रुटि की रिपोर्ट करता है। यह cgi का html कोड प्रदान नहीं करेगा।
डी। कार्तिकेयन

लागू perl -c filenameवास्तव में वाक्य रचना केवल जाँच करेगा। लेकिन perl filenameHTML आउटपुट प्रिंट करता है। यह कोई गारंटी नहीं है कि 500 ​​सीजीआई त्रुटि नहीं होगी, लेकिन यह एक अच्छा पहला परीक्षण है।
नागदेव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.