2012-08-02 28 views
5

में स्पष्ट रूप से ट्रैपिंग सिग्नल मेरे पास एक साधारण पर्ल स्क्रिप्ट है जो बस टेक्स्ट की एक पंक्ति को stdout पर प्रिंट करती है। जो मैं पूरा करना चाहता हूं वह यह है कि जब यह स्क्रिप्ट चलती है, तो अगर मैं (या कोई और) उस प्रक्रिया को रोकने के लिए एक संकेत जारी करता है, तो मैं चाहता हूं कि वह उस सिग्नल को फंसाने और साफ से बाहर निकलने के लिए तैयार करे। कोड मैं निम्नलिखितपर्ल

#!/usr/bin/perl -w 

$| = 1; 
use sigtrap 'handler' => \&sigtrap, 'HUP', 'INT','ABRT','QUIT','TERM'; 
while(1){ 
print "Working...\n"; 
sleep(2); 
} 
sub sigtrap(){ 
print "Caught a signal\n"; 
exit(1); 
} 

तरह लग रहा है यह अच्छी तरह से काम करता है जब मैं वास्तव में कमांड लाइन से Ctrl-C मारा, अगर मैं एक

kill -9 <pid> 

यह सिर्फ मर जाता है जारी करते हैं। बाहर निकलने से पहले मैं इसे निष्पादित करने के लिए कैसे प्राप्त करूं? मेरा सामान्य विचार इस ढांचे को कैप्चर करने या विफलता के लिए सर्वर रीबूट के कारण सर्वर पर मरने पर कैप्चर करने के लिए उपयोग करना है।

धन्यवाद ज्यादा अग्रिम

उत्तर

11

सिग्नल # 9 (सिगकिल) फंस नहीं जा सकता है। इस तरह यूनिक्स डिज़ाइन किया गया है।

लेकिन रखरखाव के लिए बंद होने पर सिस्टम उस सिग्नल को नहीं भेजता है। कम से कम अगर आपका डिमन सही तरीके से व्यवहार करता है। यह आम तौर पर टीईआरएम सिग्नल भेज देगा (या /etc/init.d में आपकी डेमॉन हैंडलिंग स्क्रिप्ट क्या है)। केवल प्रक्रियाएं जो टाइमआउट के बाद सही ढंग से बंद नहीं होती हैं, सिगकिल प्राप्त करेंगे।

तो आपका लक्ष्य टीईआरएम सिग्नल को सही तरीके से संभालना और /etc/init.d में रैपर स्क्रिप्ट लिखना चाहिए जिसे सिस्टम रनलेवल बदलते समय बुलाया जाएगा।

अद्यतन: आप इनिट स्क्रिप्ट के लिए Daemon::Control मॉड्यूल का उपयोग कर सकते हैं।

4

में आप अपने प्रक्रिया के लिए दो बहुत ही अलग संकेत भेज रहे हैं। कंसोल में Ctrl-C दबाकर आमतौर पर प्रक्रिया TERM INT सिग्नल भेजती है, जो - आपके कोड द्वारा निर्णय - पकड़ा और सर्विस किया जाता है। kill -9, हालांकि, सिग्नल नंबर 9 स्पष्ट रूप से भेजता है, जिसे KILL कहा जाता है। यह उन संकेतों में से एक है जिनकी सर्विसिंग को फिर से परिभाषित नहीं किया जा सकता है और इस सिग्नल की डिलीवरी हमेशा प्रक्रिया को समाप्त करती है, जो कि कर्नेल द्वारा ही की जाती है।

+3

'Ctrl-C' दबाकर 'INT' सिग्नल ** ** ** TERM' नहीं भेजता है, हालांकि एक इंटरैक्टिव प्रक्रिया के लिए डिफ़ॉल्ट कार्रवाई। 'Kill -9' के विपरीत, सिग्नल पकड़ा जा सकता है। एक 'kill -l' सिग्नल नाम सूचीबद्ध करेगा। एक 'stty -a' 'INT' के डिफ़ॉल्ट मैपिंग को 'Ctrl-C' में दिखाएगा। – JRFerguson

+0

ओच! गलतफहमी के लिए इसे साफ़ करने और क्षमा करने के लिए धन्यवाद। –

3

जहाँ तक मुझे पता है कि आप kill -9 पर कब्जा नहीं कर सकते हैं। इसके बजाय kill <pid> आज़माएं।

+2

यह एक 'टीईआरएम' प्रदान करेगा, जो कंसोल में 'Ctrl-C' दबाकर प्रभावी रूप से बराबर है। –

+0

@DanielKamilKozar धन्यवाद, जानना अच्छा है। –

+3

@DanielKamilKozar: 'Ctrl-C' दबाकर 'INT' सिग्नल ** ** ** TERM' नहीं भेजता है, हालांकि एक इंटरैक्टिव प्रक्रिया के लिए डिफ़ॉल्ट कार्रवाई डिफ़ॉल्ट है। 'Kill -9' के विपरीत, सिग्नल पकड़ा जा सकता है। एक 'kill -l' सिग्नल नाम सूचीबद्ध करेगा। एक 'stty -a' 'INT' के डिफ़ॉल्ट मैपिंग को 'Ctrl-C' में दिखाएगा। – JRFerguson