আমি কীভাবে আমার পার্ল সিজিআই স্ক্রিপ্টটির সমস্যা সমাধান করব?


100

আমার একটি পার্ল স্ক্রিপ্ট রয়েছে যা কাজ করছে না এবং কীভাবে সমস্যাটি সঙ্কুচিত করা শুরু করবেন তা আমি জানি না। আমি কি করতে পারি?


দ্রষ্টব্য: আমি প্রশ্নটি যুক্ত করছি কারণ আমি সত্যিই আমার অত্যন্ত দীর্ঘ উত্তর স্ট্যাকওভারফ্লোতে যুক্ত করতে চাই। আমি অন্যান্য উত্তরে এটির সাথে বাহ্যিকভাবে সংযুক্ত রাখি এবং এটি এখানে থাকার যোগ্য। আপনার উত্তর যুক্ত করতে কিছু সংকোচ বোধ করবেন না।


5
@ ইভান - আমার বক্তব্যটি হ'ল এই যে সি-ডাব্লু হিসাবে এখনও এটি সম্পাদনযোগ্য - যদি আপনার পর্যাপ্ত কর্মফল থাকে; সিডব্লিউর জন্য 100, অন্যথায় 2k। সুতরাং এখন আপনার 2060 টির রয়েছে আপনার নন-সিডাব্লু পোস্টগুলি সম্পাদনা করতে সক্ষম হওয়া উচিত।
মার্ক Gravell

1
: @Evan, জাদু পয়েন্ট ডানদিকের কলামে টুলটিপ্সে এখানে তালিকাভুক্ত করা হয় stackoverflow.com/privileges
cjm

যদি আপনার ওয়েব ব্রাউজারটি লাইন শব্দ দেখায়, তবে এটি পরিবর্তে পার্ল স্ক্রিপ্টটি মুদ্রণ করতে পারে। সেক্ষেত্রে
অ্যান্ড্রু গ্রিম

উত্তর:


129

এই উত্তরটি পার্ল সিজিআই স্ক্রিপ্টগুলির সাথে সমস্যার মধ্য দিয়ে কাজ করার জন্য একটি সাধারণ কাঠামো হিসাবে লক্ষ্যযুক্ত এবং মূলত পার্লমনসকে ট্রাবলশুটিং পার্ল সিজিআই স্ক্রিপ্ট হিসাবে উপস্থিত হয়েছিল । এটি আপনার মুখোমুখি হওয়া প্রতিটি সমস্যার সম্পূর্ণ গাইড নয় বা বাগ স্কোয়াশিংয়ের কোনও টিউটোরিয়াল নয়। এটি বিশ বছরের (প্লাস!) বছর ধরে সিজিআই স্ক্রিপ্টগুলি ডিবাগ করার জন্য কেবল আমার অভিজ্ঞতার সমাপ্তি। এই পৃষ্ঠাটির অনেকগুলি পৃথক বাড়ি রয়েছে বলে মনে হয় এবং মনে হয় এটি বিদ্যমান রয়েছে, তাই আমি এটিকে স্ট্যাকওভারফ্লোতে যুক্ত করছি। আপনি আমাকে bdfoy@cpan.org এ কোন মন্তব্য বা পরামর্শ পাঠাতে পারেন। এটি সম্প্রদায়ের উইকিও, তবে খুব বেশি বাদাম লাগবে না। :)


সমস্যাগুলি খুঁজে পেতে সহায়তা করার জন্য আপনি কি পার্লের অন্তর্নির্মিত বৈশিষ্ট্যগুলি ব্যবহার করছেন?

পার্ল আপনাকে আপনার কোডের প্রশ্নবিদ্ধ অংশ সম্পর্কে সতর্ক করতে দিতে সতর্কতা চালু করুন। আপনি -wস্যুইচ সহ কমান্ড লাইন থেকে এটি করতে পারেন যাতে আপনার কোনও কোড পরিবর্তন করতে বা প্রতিটি ফাইলে একটি প্রগমা যোগ করতে হয় না:

 % perl -w program.pl

যাইহোক, আপনার নিজের warningsসমস্ত ফাইলগুলিতে প্রগমা যুক্ত করে আপনার সর্বদা প্রশ্নযুক্ত কোড সাফ করার জন্য বাধ্য করা উচিত :

 use warnings;

সংক্ষিপ্ত সতর্কতা বার্তার চেয়ে আপনার যদি আরও তথ্যের প্রয়োজন হয় তবে আরও তথ্য diagnosticsপেতে প্রগমাটি ব্যবহার করুন বা পারল্ডিয়াগ ডকুমেন্টেশনটি দেখুন:

 use diagnostics;

আপনি কি প্রথমে একটি বৈধ সিজিআই শিরোনাম আউটপুট করেছেন?

সার্ভারটি সিজিআই স্ক্রিপ্ট থেকে প্রথম আউটপুট সিজিআই শিরোনাম হওয়ার প্রত্যাশা করছে। সাধারণত এটি সিজিআই.এম.পি এবং এর ডেরাইভেটিভস, এর মতো print "Content-type: text/plain\n\n";বা সাধারণ হতে পারে । কিছু সার্ভার স্ট্যান্ডার্ড আউটপুট (চালু) এর আগে প্রদর্শিত ত্রুটি আউটপুট (অন ) এর প্রতি সংবেদনশীলprint header()STDERRSTDOUT ) এর ।

ব্রাউজারে ত্রুটি প্রেরণ চেষ্টা করুন

এই লাইন যুক্ত করুন

 use CGI::Carp 'fatalsToBrowser';

আপনার লিপি। এটি ব্রাউজার উইন্ডোতে সংকলন ত্রুটিগুলিও প্রেরণ করে। উত্পাদনের পরিবেশে যাওয়ার আগে এটিকে সরাতে ভুলবেন না, কারণ অতিরিক্ত তথ্য সুরক্ষা ঝুঁকি হতে পারে।

ত্রুটি লগ কি বলেছিল?

সার্ভারগুলি ত্রুটি লগগুলি রাখে (বা তাদের কমপক্ষে হওয়া উচিত)। সার্ভার থেকে এবং আপনার স্ক্রিপ্ট থেকে ত্রুটি আউটপুট সেখানে প্রদর্শিত হবে। ত্রুটি লগটি সন্ধান করুন এবং দেখুন এটি কী বলে। লগ ফাইলগুলির জন্য কোনও মানক স্থান নেই। তাদের অবস্থানের জন্য সার্ভার কনফিগারেশনটি দেখুন বা সার্ভার প্রশাসককে জিজ্ঞাসা করুন। আপনি সিজিআই :: কার্পের মতো সরঞ্জামগুলিও ব্যবহার করতে পারেন নিজের লগ ফাইলগুলি রাখতে ।

স্ক্রিপ্টের অনুমতিগুলি কী কী?

যদি আপনি "অনুমতি অস্বীকৃত" বা "পদ্ধতি প্রয়োগ করা হয়নি" এর মতো ত্রুটি দেখতে পান তবে সম্ভবত এটির অর্থ হ'ল আপনার স্ক্রিপ্টটি ওয়েব সার্ভার ব্যবহারকারীর দ্বারা পঠনযোগ্য এবং সম্পাদনযোগ্য নয়। ইউনিক্স এর স্বাদে তারিখে, 755 মোডে পরিবর্তন বাঞ্ছনীয়: chmod 755 filename। 777 এ কোনও মোড কখনও সেট করবেন না!

আপনি ব্যবহার করছেন use strict?

মনে রাখবেন পার্ল আপনি যখন এগুলি প্রথম ব্যবহার করেন তখন স্বয়ংক্রিয়ভাবে ভেরিয়েবল তৈরি করে। এটি একটি বৈশিষ্ট্য, তবে কখনও কখনও আপনি যদি কোনও ভেরিয়েবলের নামটি ভুল টাইপ করেন তবে বাগের কারণ হতে পারে। প্রগমা use strict আপনাকে সেই ধরণের ত্রুটিগুলি খুঁজে পেতে সহায়তা করবে। আপনি এটি ব্যবহার না করা অবধি বিরক্তিকর, তবে আপনার প্রোগ্রামিং কিছুক্ষণ পরে উন্নত হবে এবং আপনি বিভিন্ন ভুল করতে মুক্ত হবেন free

স্ক্রিপ্টটি কি সংকলন করে?

আপনি -c স্যুইচটি ব্যবহার করে সংকলন ত্রুটিগুলি পরীক্ষা করতে পারেন। রিপোর্ট করা প্রথম ত্রুটিগুলিতে মনোনিবেশ করুন। ধুয়ে ফেলুন, পুনরাবৃত্তি করুন। আপনি যদি সত্যিই অদ্ভুত ত্রুটি পেয়ে থাকেন তবে আপনার স্ক্রিপ্টের সঠিক লাইনের শেষ রয়েছে কিনা তা পরীক্ষা করে দেখুন। আপনি যদি বাইনারি মোডে এফটিপি করেন, সিভিএস থেকে চেকআউট বা অন্য কোনও কিছু যা লাইন শেষের অনুবাদটি পরিচালনা করে না, ওয়েব সার্ভার আপনার স্ক্রিপ্টটিকে একটি বড় লাইন হিসাবে দেখতে পারে। ASCII মোডে পার্ল স্ক্রিপ্টগুলি স্থানান্তর করুন।

স্ক্রিপ্টটি কি অনিরাপদ নির্ভরতা সম্পর্কে অভিযোগ করছে?

যদি আপনার স্ক্রিপ্টটি অনিরাপদ নির্ভরতা সম্পর্কে অভিযোগ করে, আপনি সম্ভবত -Tদাগ মোড চালু করতে স্যুইচটি ব্যবহার করছেন , এটি একটি ভাল জিনিস কারণ এটি আপনাকে শেলটিতে চেক করা ডেটা পাস করার কারণে রাখে। যদি এটি অভিযোগ করে তবে এটি আমাদের আরও সুরক্ষিত স্ক্রিপ্ট লিখতে সহায়তা করার জন্য এটি কাজ করছে। প্রোগ্রামের (অর্থাত্ পরিবেশ) বাইরে থেকে উত্পন্ন কোনও তথ্য কলঙ্কিত বলে বিবেচিত হয়। পরিবেশের পরিবর্তনশীল যেমন PATHএবং LD_LIBRARY_PATH বিশেষত ঝামেলাজনক। আমার পরামর্শ অনুসারে আপনাকে এগুলি নিরাপদ মান হিসাবে সেট করতে হবে বা সম্পূর্ণ আনসেট করতে হবে। আপনার যাইহোক নিখুঁত পাথ ব্যবহার করা উচিত। যদি কলঙ্কিত চেকিং অন্য কোনও বিষয়ে অভিযোগ করে তবে তা নিশ্চিত করে নিন যে আপনি ডেটাটি অকেজো করেছেন। বিশদ জন্য perlsec ম্যান পৃষ্ঠা দেখুন ।

কমান্ড লাইন থেকে চালানোর সময় কী ঘটে?

কমান্ড লাইন থেকে চালানোর সময় স্ক্রিপ্টটি কী প্রত্যাশা করে? শিরোনাম আউটপুট কি প্রথমে একটি ফাঁকা রেখা অনুসরণ করে? মনে রাখবেন যে STDERRসাথে মার্জ করা যেতে পারে STDOUT যদি আপনি একটি টার্মিনাল (যেমন একটি ইন্টারেক্টিভ অধিবেশন) এ আছে, এবং বাফার উপলব্ধ কারণে এটা কল্পনাপ্রসূত অনুক্রমে দেখানো হতে পারে। $|সত্যিকারের মানটিতে সেট করে পার্লের অটোফ্ল্যাশ বৈশিষ্ট্যটি চালু করুন । সাধারণত আপনি $|++;সিজিআই প্রোগ্রামগুলিতে দেখতে পাবেন । একবার সেট হয়ে গেলে, প্রতিটি মুদ্রণ এবং লেখা তাত্ক্ষণিকভাবে বাফার হওয়ার পরিবর্তে আউটপুটে যাবে। প্রতিটি ফাইলহ্যান্ডেলের জন্য আপনাকে এটি সেট করতে হবে। selectডিফল্ট ফাইলহ্যান্ডেল পরিবর্তন করতে ব্যবহার করুন , এর মতো:

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

যেভাবেই হোক, প্রথম জিনিস আউটপুটটি সিজিআই শিরোনাম হওয়া উচিত তার পরে একটি ফাঁকা লাইন।

আপনি যখন সিজিআই-এর মতো পরিবেশের সাথে কমান্ড লাইন থেকে চালাবেন তখন কী হবে?

ওয়েব সার্ভার পরিবেশটি সাধারণত আপনার কমান্ড লাইন পরিবেশের চেয়ে অনেক বেশি সীমাবদ্ধ থাকে এবং অনুরোধ সম্পর্কে অতিরিক্ত তথ্য থাকে। যদি আপনার স্ক্রিপ্টটি কমান্ড লাইন থেকে ঠিকঠাক চলতে পারে তবে আপনি ওয়েব সার্ভারের পরিবেশের অনুকরণের চেষ্টা করতে পারেন। সমস্যাটি যদি উপস্থিত হয় তবে আপনার পরিবেশ সমস্যা রয়েছে।

এই ভেরিয়েবলগুলি আনসেট করুন বা অপসারণ করুন

  • PATH
  • LD_LIBRARY_PATH
  • সমস্ত ORACLE_*পরিবর্তনশীল

এই ভেরিয়েবল সেট করুন

  • REQUEST_METHOD(সেট GET, HEADঅথবা POSTযা প্রযোজ্য)
  • SERVER_PORT (সাধারণত 80 এ সেট করা হয়)
  • REMOTE_USER (যদি আপনি সুরক্ষিত অ্যাক্সেস স্টাফগুলি করেন)

CGI.pm(> ২.) Recent ) এর সাম্প্রতিক সংস্করণগুলিতে -debugপুরানো (দরকারী) আচরণ পেতে পতাকাটি দরকার , যাতে আপনার এটিকে আপনার CGI.pmআমদানিতে যুক্ত করতে হতে পারে ।

use CGI qw(-debug)

আপনি ব্যবহার করছেন die()বা warn?

আপনি STDERRযদি তাদের নতুন সংজ্ঞা না দিয়ে থাকেন তবে এই ফাংশনগুলি মুদ্রণ করে। তারা কোনও সিজিআই শিরোনাম আউটপুট দেয় না। আপনি সিজিআই :: কার্পের মতো প্যাকেজগুলির সাথে একই কার্যকারিতাটি পেতে পারেন

আপনি ব্রাউজার ক্যাশে সাফ করার পরে কি হবে?

আপনি যদি মনে করেন যে আপনার স্ক্রিপ্টটি সঠিক কাজ করছে এবং আপনি যখন অনুরোধটি ম্যানুয়ালি সম্পাদন করেন আপনি সঠিক আউটপুট পান, ব্রাউজারটি অপরাধী হতে পারে। ক্যাশে সাফ করুন এবং পরীক্ষার সময় ক্যাশের আকার শূন্যে সেট করুন। মনে রাখবেন যে কিছু ব্রাউজারগুলি সত্যিই বোকা এবং আপনি এটি করতে বললেও নতুন সামগ্রীটি পুনরায় লোড করবে না। এটি ইউআরএল পাথের ক্ষেত্রে একই ক্ষেত্রে প্রচলিত রয়েছে তবে সামগ্রীতে পরিবর্তন হয় (যেমন ডায়নামিক চিত্র)।

আপনি যেখানে মনে করেন স্ক্রিপ্টটি এটি?

কোনও স্ক্রিপ্টে ফাইল সিস্টেমের পথটি সরাসরি স্ক্রিপ্টের ইউআরএল পাথের সাথে সম্পর্কিত নয়। এটি পরীক্ষা করতে আপনাকে একটি স্বল্প পরীক্ষার স্ক্রিপ্ট লিখতে হবে এমনকি আপনার সঠিক ডিরেক্টরি রয়েছে তা নিশ্চিত করুন। তদুপরি, আপনি কি নিশ্চিত যে আপনি সঠিক ফাইলটি সংশোধন করছেন? যদি আপনি আপনার পরিবর্তনগুলির সাথে কোনও প্রভাব না দেখেন তবে আপনি অন্য কোনও ফাইলকে সংশোধন করতে বা ভুল জায়গায় কোনও ফাইল আপলোড করছেন। (এটি, যাইহোক, এ জাতীয় সমস্যার আমার সবচেয়ে ঘন ঘন কারণ;)

আপনি কি ব্যবহার করছেন CGI.pm, বা এটির একটি উদ্দীপনা?

আপনার সমস্যা সিজিআই ইনপুট পার্স সঙ্গে সম্পর্কযুক্ত এবং আপনার মত একটি বহুল পরীক্ষিত মডিউল ব্যবহার না করেন তাহলে CGI.pm, CGI::Request, CGI::Simpleবা CGI::Lite, মডিউলের ব্যবহার এবং জীবনের সঙ্গে পেতে। CGI.pmএকটি আছেcgi-lib.pl সামঞ্জস্যতা মোড রয়েছে যা আপনাকে পুরানো সিজিআই পার্সার বাস্তবায়নের কারণে ইনপুট সমস্যাগুলি সমাধান করতে সহায়তা করতে পারে।

আপনি কি পরম পথ ব্যবহার করেছেন?

আপনি যদি systemব্যাক টিক্স, বা অন্যান্য আইপিসি সুবিধা সহ বাহ্যিক কমান্ডগুলি চালাচ্ছেন তবে আপনার বাহ্যিক প্রোগ্রামের জন্য একটি নিখুঁত পথ ব্যবহার করা উচিত। আপনি কী চালাচ্ছেন তা কেবল আপনিই জানেন না তবে আপনি কিছু সুরক্ষা সমস্যাও এড়িয়ে চলেছেন। আপনি যদি পড়া বা লেখার জন্য ফাইলগুলি খুলছেন তবে একটি নিখুঁত পথ ব্যবহার করুন। সিজিআই স্ক্রিপ্টের বর্তমান ডিরেক্টরি সম্পর্কে আপনার চেয়ে আলাদা ধারণা থাকতে পারে। বিকল্পভাবে, আপনি chdir()সঠিক জায়গায় রাখার জন্য আপনি একটি স্পষ্ট করতে পারেন।

আপনি কি আপনার ফেরতের মূল্য পরীক্ষা করেছেন?

বেশিরভাগ পার্ল ফাংশন আপনাকে জানায় যে তারা কাজ করেছে কি না এবং $!ব্যর্থতা সেট করে। আপনি কি ফেরতের মানটি পরীক্ষা করে $!ত্রুটি বার্তাগুলির জন্য পরীক্ষা করেছেন? আপনি $@ব্যবহার করছেন কিনা তা পরীক্ষা করে দেখেছেন eval?

পার্লের কোন সংস্করণ আপনি ব্যবহার করছেন?

পারেলের সর্বশেষতম স্থিতিশীল সংস্করণ 5.28 (এটি কখন শেষবার সম্পাদিত হয়েছিল তার উপর নির্ভর করে)। আপনি কি পুরানো সংস্করণ ব্যবহার করছেন? পার্লের বিভিন্ন সংস্করণে সতর্কতার বিভিন্ন ধারণা থাকতে পারে।

আপনি কোন ওয়েব সার্ভার ব্যবহার করছেন?

বিভিন্ন সার্ভার একই পরিস্থিতিতে ভিন্নভাবে কাজ করতে পারে। একই সার্ভার পণ্যটি বিভিন্ন কনফিগারেশনের সাথে আলাদাভাবে কাজ করতে পারে। সাহায্যের জন্য যে কোনও অনুরোধে আপনি যতটা পারেন এই তথ্যকে অন্তর্ভুক্ত করুন।

আপনি সার্ভার ডকুমেন্টেশন চেক করেছেন?

গুরুতর সিজিআই প্রোগ্রামারদের সার্ভার সম্পর্কে যতটা সম্ভব জানা উচিত - কেবল সার্ভারের বৈশিষ্ট্য এবং আচরণই নয়, স্থানীয় কনফিগারেশনও রয়েছে। আপনি যদি বাণিজ্যিক পণ্য ব্যবহার করেন তবে আপনার সার্ভারের জন্য ডকুমেন্টেশন আপনার কাছে উপলভ্য নয়। অন্যথায়, ডকুমেন্টেশনটি আপনার সার্ভারে থাকা উচিত। যদি তা না হয় তবে ওয়েবে এটি সন্ধান করুন।

আপনি কি সংরক্ষণাগার অনুসন্ধান করেছেন comp.infosystems.www.authoring.cgi?

এই ব্যবহারটি কার্যকর হতে পারে তবে সমস্ত ভাল পোস্টার মারা গেছে বা ঘুরে বেড়িয়েছে।

সম্ভবত কারওর আগে আপনার সমস্যা হয়েছে এবং কেউ (সম্ভবত আমি) এই নিউজগ্রুপে এর জবাব দিয়েছে। যদিও এই নিউজগ্রুপটি তার শেষ দিনটি কেটে গেছে, অতীত থেকে সংগৃহীত জ্ঞান কখনও কখনও দরকারী হতে পারে।

আপনি একটি সংক্ষিপ্ত পরীক্ষার স্ক্রিপ্ট দিয়ে সমস্যাটি পুনরুত্পাদন করতে পারেন?

বড় সিস্টেমে, অনেকগুলি ঘটতে থাকায় কোনও বাগ সনাক্ত করতে সমস্যা হতে পারে। সংক্ষিপ্ততম স্ক্রিপ্টের সাহায্যে সমস্যা আচরণটি পুনরুত্পাদন করার চেষ্টা করুন। সমস্যাটি জেনে রাখা বেশিরভাগ স্থির। এটি অবশ্যই সময় সাশ্রয়ী হতে পারে, তবে আপনি এখনও সমস্যাটি খুঁজে পান নি এবং আপনি বিকল্পগুলির বাইরে চলেছেন। :)

আপনি কি কোনও সিনেমা দেখার সিদ্ধান্ত নিয়েছেন?

সিরিয়াসলি। কখনও কখনও আমরা সমস্যার মধ্যে এমনভাবে আবদ্ধ হতে পারি যে আমরা "পার্সেপুটিভ ট্রাইরিং" (টানেলের দৃষ্টি) বিকাশ করি। কিছুটা বিরতি, এক কাপ কফি পান, বা [ডিউক নোকেম, কোয়েক, ডুম, হ্যালো, সিওডি] তে খারাপ কিছু লোককে ব্লাস্ট করে ফেলা আপনাকে সমস্যাটি পুনরায় যোগাযোগ করার জন্য একটি নতুন দৃষ্টিভঙ্গি দিতে পারে।

আপনি কি সমস্যাটি ভোকালাইজ করেছেন?

সিরিয়াসলি আবার। কখনও কখনও উচ্চস্বরে সমস্যাটি ব্যাখ্যা করা আমাদের নিজের উত্তরগুলির দিকে নিয়ে যায়। পেঙ্গুইন (প্লাশ খেলনা) এর সাথে কথা বলুন কারণ আপনার সহকর্মীরা শুনছেন না। আপনি যদি এটি একটি গুরুতর ডিবাগিং সরঞ্জাম হিসাবে আগ্রহী হন (এবং আপনি যদি এখনই সমস্যাটি না পেয়ে থাকেন তবে আমি এটির প্রস্তাব দিই), আপনি কম্পিউটার প্রোগ্রামিংয়ের সাইকোলজিটি পড়তেও পছন্দ করতে পারেন ।


4
আপনার উত্তর যুক্ত করতে কিছু সংকোচ বোধ করবেন না।
brian d foy

দেখে মনে হচ্ছে আপনি সিজিআই মেটা FAQ- এর লিঙ্কটি সরাতে চাইবেন। 5.12.1 "স্থিতিশীল" হিসাবে বিবেচিত হয়?
সাপ প্লিসকেন

1
$|=1তার বদলে কেন হবে না $|++?
পুনরায় পোস্টার

এর $|=1বদলে কেন $|++? এটি আসলে কোনও পার্থক্য করে না, এবং তারপরেও, $|যাদুকরী।
ব্রায়ান ডি বন্ধু

2
উত্তম উত্তর, আমি মনে করি এটি উল্লেখ করার মতো হতে পারে যে এর মধ্যে কয়েকটি সমাধান নিখুঁতভাবে সমস্যার সমাধানের জন্য হওয়া উচিত এবং উত্পাদন কোডে না রাখা উচিত। use strictসাধারণত সর্বদা ব্যবহার করা ভাল, তবে ব্যবহারের fatalsToBrowserক্ষেত্রে উত্পাদনের পরামর্শ দেওয়া যাবে না, বিশেষত আপনি যদি ব্যবহার করছেন die
ভোলআরন


7

আপনি ডিবাগ করার সময় আপনি কি ত্রুটি হ্যান্ডলার ব্যবহার করছেন?

dieবিবৃতি এবং অন্যান্য মারাত্মক রান-টাইম এবং সংকলন-সময় ত্রুটিগুলি এতে মুদ্রিত হয় STDERRযা খুঁজে পাওয়া শক্ত এবং আপনার সাইটের অন্যান্য ওয়েব পৃষ্ঠাগুলির বার্তাগুলির সাথে জড়িত হতে পারে। আপনি যখন আপনার স্ক্রিপ্টটি ডিবাগ করছেন, তখন কোনওভাবেই আপনার ব্রাউজারে মারাত্মক ত্রুটি বার্তাগুলি প্রদর্শন করা ভাল ধারণা।

এটি করার একটি উপায় কল করা

   use CGI::Carp qw(fatalsToBrowser);

আপনার স্ক্রিপ্ট শীর্ষে। এই কলটি আপনার ব্রাউজারে কোনও $SIG{__DIE__}হ্যান্ডলার ইনস্টল করবে ( পার্লওয়ার দেখুন ) মারাত্মক ত্রুটি প্রদর্শন করবে, যদি প্রয়োজন হয় তবে এটি বৈধ শিরোনামের সাথে প্রিপেন্ড করে। আরেকটি সিজিআই ডিবাগ কৌতুক আগে আমি কখনো শুনেছেন ব্যবহৃত আমি 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
@Ether: <DATA>একটি যাদু filehandle যা বর্তমান স্ক্রিপ্ট দিয়ে শুরু সার্চ __END__। যোগদান এটির তালিকা প্রসঙ্গ সরবরাহ করে, সুতরাং <fh> আইটেমের জন্য একটি অ্যারে, এক লাইন দেয়। তারপরে যোগ দিন এটি আবার একসাথে রাখে (এটি '' এর সাথে যোগ দিয়ে)। অবশেষে, eval।
ডারোবার্ট

@ ইথার: লাইন 2 লেখার আরও পঠনযোগ্য উপায় eval join(q{}, <DATA>);
হ'ল

@ oberডবার্ট: আসলে ,____ ডেটা তথ্য বিভাগ শুরু করার জন্য ব্যবহৃত টোকেন, __END__ নয় (আমি মনে করি এটি আমার বিভ্রান্তি ছিল)।
ইথার

1
@ ইথার: ঠিক আছে, তারা উভয়ই শীর্ষ স্তরের স্ক্রিপ্টে (পারলডাটা ম্যানপেজ অনুসারে) কাজ করে। তবে যেহেতু ডেটা পছন্দ করা হয়, তাই আমি উত্তরটি পরিবর্তন করেছি।
ডারোবার্ট

@ডারবার্ট: ডক লিঙ্কের জন্য ধন্যবাদ; আমি __END__ এর পিছনের সামঞ্জস্যতার আচরণ সম্পর্কে জানতাম না!
ইথার

7

আমি অবাক হয়েছি কীভাবে কেউ PERLDB_OPTSবিকল্প হিসাবে ডাকে না RemotePort; যদিও স্বীকার করা যায় যে ওয়েবে অনেকগুলি কার্যকরী উদাহরণ নেই ( RemotePortএমনকি এটিতেও উল্লেখ করা হয়নি) পার্ল্ডেবুগেও হয়নি ) - এবং এটির সাথে আমার উপস্থিত হওয়া খুব সমস্যাযুক্ত ছিল, তবে এটি এখানে রয়েছে (এটি একটি লিনাক্স উদাহরণ হিসাবে)।

একটি যথাযথ উদাহরণ করার জন্য প্রথমে আমার এমন কিছু দরকার ছিল যা একটি সিজিআই ওয়েব সার্ভারের খুব সাধারণ সিমুলেশন করতে পারে, সম্ভবত একক কমান্ড লাইনের মাধ্যমে। সিজিএস চালানোর জন্য সিম্পল কমান্ড লাইন ওয়েব সার্ভারটি সন্ধান করার পরে (perlmonks.org) , আমি আইও :: সমস্ত - এই পরীক্ষার জন্য প্রযোজ্য একটি ক্ষুদ্র ওয়েব সার্ভারকে পেয়েছি ।

এখানে, আমি /tmpডিরেক্টরিতে কাজ করব ; সিজিআই স্ক্রিপ্টটি হবে /tmp/test.pl(নীচে অন্তর্ভুক্ত)। নোট করুন যে IO::Allসার্ভারটি কেবল সিজিআই হিসাবে একই ডিরেক্টরিতে এক্সিকিউটেবল ফাইলগুলি পরিবেশন করবে, তাই chmod +x test.plএখানে প্রয়োজনীয়। সুতরাং, সাধারণ সিজিআই পরীক্ষা চালানোর জন্য, আমি ডিরেক্টরিটি /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, এখানে এটি দেখেছি: পার্ল 如何 রিমোট ডিবাগ? )। সুতরাং, প্রথমে 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

এটি এক ধরণের জটিল জিনিস - শেল স্ক্রিপ্ট দেখুন - আমি কীভাবে আমার শেবাং-এ পরিবেশের পরিবর্তনগুলি ব্যবহার করতে পারি? - ইউনিক্স এবং লিনাক্স স্ট্যাক এক্সচেঞ্জ । তবে, এখানে কৌশলটি হ'ল দোভাষীকে কাঁটাচামচা করে না বলে মনে হচ্ছে - সুতরাং একবার এটি আঘাত করলে আমরা তা করি না , পরিবর্তে আমরা "স্পষ্টতই", এবং মূলত আমাদের স্ক্রিপ্টটি "উত্স" বলি (দেখুন আমি কীভাবে চালাব পার্ল স্ক্রিপ্ট একটি পার্ল স্ক্রিপ্টের মধ্যে থেকে? )।perltest.plexecperltest.pldo

এখন আমাদের 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; এবং আমাদের nc7234 বন্দরে ডিবাগ সংযোগের জন্য শুনছি - যাতে আমরা শেষ পর্যন্ত অন্য টার্মিনাল উইন্ডোটি খুলতে পারি, ডিরেক্টরিতে পরিবর্তন করতে পারি /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রিমোট ডিবাগার মোডে শুরু হবে will সুতরাং, স্ক্রিপ্টের প্রয়োগটি বিরতি দেবে - এবং তাই ওয়েব ব্রাউজারটি লক হয়ে যাবে, ডেটার জন্য অপেক্ষা করবে। আমরা এখন 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"রান" জন্য টাইপ করতে পারি (এবং এন্টার) - এবং স্ক্রিপ্টটি ব্রেকপয়েন্ট স্টেটমেন্টটি চালিয়ে যায় (আরও দেখুন) পার্লটিতে আরও দেখুন, between এর মধ্যে পার্থক্য কী is ডিবি :: একক = 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

অবশ্যই, ওয়েব সার্ভারটি চালানো ছাড়াই এই ধরণের ডিবাগ করা যেতে পারে - তবে, এখানে পরিষ্কার জিনিসটি হ'ল আমরা ওয়েব সার্ভারটি একেবারেই স্পর্শ করি না; আমরা একটি ওয়েব ব্রাউজার থেকে "স্থানীয়ভাবে" (সিজিআইয়ের জন্য) মৃত্যুদন্ড কার্যকর করি - এবং সিজিআই স্ক্রিপ্টে নিজেই প্রয়োজন কেবল পরিবর্তন হ'ল শেবাংয়ের পরিবর্তন (এবং অবশ্যই, শেবাং র‌্যাপার স্ক্রিপ্টের উপস্থিতি, একই এক্সিকিউটেবল ফাইল হিসাবে ডিরেক্টরি)।

ঠিক আছে, আশা করি এটি কারও সহায়ক হয়েছে - আমি নিশ্চিত :)
চিয়ার্স লেখার পরিবর্তে এটির পক্ষে হোঁচট খেতে পছন্দ করতাম !


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

সত্যিই আপনি এই পোস্টের উপরে সমস্ত মজাদার স্টাফ করতে পারেন। তবুও, আমি খুঁজে পাওয়া সবচেয়ে সহজ এবং সক্রিয় সমাধানটি হ'ল "এটি মুদ্রণ করুন"।

উদাহরণস্বরূপ: (সাধারণ কোড)

`$somecommand`;

আমি এটি যা করতে চাই তা এটি করছে কিনা তা দেখার জন্য: (শ্যুটিংয়ের সমস্যা)

print "$somecommand";

1

সম্ভবত এটি উল্লেখ করার মতো হবে যে পার্ল সর্বদা আপনাকে বলবে যে আপনি যখন কমান্ড লাইন থেকে পার্ল স্ক্রিপ্টটি সম্পাদন করেন তখন ত্রুটিটি কোন লাইনে ঘটে। (উদাহরণস্বরূপ একটি এসএসএইচ সেশন)

অন্য সব ব্যর্থ হলে আমি সাধারণত এটি করব। আমি সার্ভারে এসএসএইচ করব এবং ম্যানুয়ালি পার্ল স্ক্রিপ্টটি সম্পাদন করব। উদাহরণ স্বরূপ:

% perl myscript.cgi 

যদি কোনও সমস্যা হয় তবে পার্ল আপনাকে এটি সম্পর্কে বলবে। এই ডিবাগিং পদ্ধতিটি কোনও ফাইল অনুমতি সম্পর্কিত সমস্যা বা ওয়েব ব্রাউজার বা ওয়েব সার্ভার সমস্যাগুলি সরিয়ে দেয়।


পার্ল সর্বদা লাইন নম্বরটি আপনাকে জানায় না যেখানে কোনও ত্রুটি ঘটে। এটি আপনাকে লাইন নম্বরটি জানায় যেখানে এটি বুঝতে পারে যে এখানে কিছু ভুল আছে wrong ত্রুটি সম্ভবত ইতিমধ্যে ঘটেছে।
brian d foy

0

আপনি নীচের কমান্ডটি ব্যবহার করে টার্মিনালে পার্ল সিজি-স্ক্রিপ্টটি চালাতে পারেন

 $ perl filename.cgi

এটি কোডটি ব্যাখ্যা করে এবং এইচটিএমএল কোড সহ ফলাফল সরবরাহ করে tএটি যদি ত্রুটিটি রিপোর্ট করে report


1
দুঃখিত, $ perl -c filename.cgi কমান্ডটি কোডের বাক্য গঠনটিকে বৈধতা দেয় এবং যদি ত্রুটিটি থাকে তবে রিপোর্ট করে। এটি সিগির এইচটিএমএল কোড সরবরাহ করবে না।
ডি কার্তিকেইকান

আমন্ত্রণ perl -c filenameকরা প্রকৃতপক্ষে কেবল সিনট্যাক্স পরীক্ষা করবে। কিন্তু perl filenameএইচটিএমএল আউটপুট মুদ্রণ করে না। এটির কোনও গ্যারান্টি নেই যে যদিও 500 সিজিআই ত্রুটি হবে না তবে এটি একটি ভাল প্রথম পরীক্ষা।
নাগেভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.