क्या हो रहा है
जब आप Ctrl+ दबाते हैं C, तो SIGINT
संकेत पूरे अग्रभूमि प्रक्रिया समूह को दिया जाता है । यहां इसे find
प्रोसेस और कॉलिंग शेल प्रक्रिया दोनों में भेजा जाता है। find
तुरंत बाहर निकलने से प्रतिक्रिया करता है, और खोल जाल को कॉल करके प्रतिक्रिया करता है।
यदि ट्रैप रिटर्न में कोड (यानी कॉल नहीं करता है exit
), सिग्नल द्वारा बाधित किए गए एक के बाद निष्पादन कमांड के साथ आगे बढ़ता है। यहां, find
स्क्रिप्ट के अंत के बाद कमांड आती है, इसलिए स्क्रिप्ट तुरंत वैसे भी बाहर निकल जाती है। लेकिन आप एक और कमांड जोड़कर 0 और 1 में अंतर देख सकते हैं:
find /
echo "find returned $?"
एक तरीका जो आप चाहते हैं (लेकिन शायद ऐसा नहीं करना चाहिए)
आप जो चाहते है वो कर सकते हैं; लेकिन मेरे जवाब का यह हिस्सा एक वास्तविक समस्या को हल करने की तुलना में शेल प्रोग्रामिंग की खोज के बारे में अधिक है।
- एक डिजाइन मामले के रूप में, एक पुनरारंभ करने योग्य संकेत वह नहीं है जो आप आमतौर पर उस तरह के अपेक्षाकृत सरल कार्यक्रमों की अपेक्षा करते हैं जो शेल स्क्रिप्ट आमतौर पर होते हैं। उम्मीद है कि Ctrl+ Cस्क्रिप्ट को मार देगा।
- जैसा कि आप नीचे देखेंगे, यह वैसे भी शेल की क्षमताओं को थोड़ा दूर खींचता है।
आप हत्या से बचना चाहते हैं find
, तो आप में यह शुरू करने की आवश्यकता पृष्ठभूमि : find / &
। फिर सामान्य रूप से बाहर निकलने के लिए प्रतीक्षा करने के लिए wait
बिलिन का उपयोग करें। एक सिग्नल wait
बिल्ट-इन को बाधित करेगा , जिसे आप एक लूप में चला सकते हैं जब तक आपको एक सिग्नल नहीं मिलता है जिसे आप प्रचार करना चाहते हैं। फिर kill
काम को मारने के लिए उपयोग करें।
hell () {
echo "Do you want to quit? Press 1 for yes and 0 for no"
read n
if [ "$n" = 1 ]; then
# Kill the job if it's running, then exit
if [ -n "$job_pid" ]; then kill $job_pid; fi
exit 1
fi
}
job_pid=
trap "hell" SIGINT
# Start a demo job in the background
for i in 1 2 3 4 5; do date; sleep 1; done &
job_pid=$!
# Call wait in a loop; wait will return 0 if the job exits, and 128+$signum if interrupted by a signal.
while ! wait; do
echo "resuming wait"
done
job_pid=
echo last exit code: $?
शेल में इस दृष्टिकोण की सीमाएँ हैं:
- एक दौड़ की स्थिति है: यदि आप नौकरी खत्म होने के बाद Ctrl+ दबाते हैं , Cलेकिन
job_pid=
लाइन से पहले , सिग्नल हैंडलर को मारने की कोशिश करेगा $jobpid
, लेकिन यह प्रक्रिया अब मौजूद नहीं है (यहां तक कि एक ज़ोंबी के रूप में, क्योंकि wait
पहले से ही इसे समाप्त कर दिया है), और प्रक्रिया हो सकता है कि आईडी किसी अन्य प्रक्रिया द्वारा पुन: उपयोग किया गया हो। यह शेल में आसानी से ठीक नहीं है (हो सकता है कि इसके लिए हैंडलर सेट करके SIGCHLD
?)।
- यदि आपको नौकरी से रिटर्न की स्थिति की आवश्यकता है, तो आपको
wait $job_pid
फॉर्म का उपयोग करने की आवश्यकता है । लेकिन तब आप wait
"नौकरी से एक सिग्नल द्वारा मारे गए" (न ही "एक वापसी की स्थिति ”128 के साथ अपने स्वयं के समझौते के समाप्त होने से", लेकिन यह खोल में एक सामान्य तथ्य है "भेद कर सकते हैं" प्रोग्रामिंग)।
- यह आसानी से विस्तार नहीं होगा अगर सभी को कई subjobs में। ध्यान दें कि जाल और संकेतों का व्यवहार अक्सर आश्चर्यचकित करता है जब आप अधिकांश शेल कार्यान्वयनों में मूल बातों से परे जाते हैं (केवल ksh यह अच्छी तरह से करता है)।
इन सीमाओं को पार करने के लिए, पर्ल या पाइथन जैसी कट्टर भाषा का उपयोग करें।