आपकी killआज्ञा पीछे की ओर है।
कई यूनिक्स आज्ञाओं की तरह, एक विकल्प जो माइनस से शुरू होता है, अन्य तर्कों से पहले पहले आना चाहिए।
अगर आप लिखेंगे
kill -INT 0
यह -INTएक विकल्प के रूप में देखता है , और वर्तमान प्रक्रिया समूह में सभी प्रक्रियाओं के SIGINTलिए भेजता है 0( 0एक विशेष संख्या का अर्थ है)।
लेकिन अगर आप लिखेंगे
kill 0 -INT
यह देखता है 0, निर्णय लेता है कि कोई और विकल्प नहीं है, इसलिए SIGTERMडिफ़ॉल्ट रूप से उपयोग करता है। और वर्तमान प्रक्रिया समूह को भेजता है , जैसा कि आपने किया था
kill -TERM 0 -INT
(यह भी भेजने की कोशिश करेगा SIGTERMकरने के लिए -INTहै, जो एक सिंटैक्स त्रुटि का कारण होता है, लेकिन यह भेजता है SIGTERMके लिए 0पहले, और हो जाता है कभी नहीं है कि अब तक।)
तो आपका मुख्य स्क्रिप्ट एक हो रही है SIGTERMइससे पहले कि इसे चलाने के लिए हो जाता है waitऔर echo DONE।
जोड़ना
trap 'echo got SIGTERM' TERM
शीर्ष पर, बस के बाद
trap 'killall' INT
और इसे साबित करने के लिए इसे फिर से चलाएं।
जैसा कि स्टीफन चेज़ेलस बताते हैं, आपके पृष्ठभूमि वाले बच्चे ( process1आदि) SIGINTडिफ़ॉल्ट रूप से अनदेखा कर देंगे ।
किसी भी मामले में, मुझे लगता है कि भेजने से SIGTERMअधिक समझ में आएगा।
अंत में, मुझे यकीन नहीं है कि kill -process groupपहले बच्चों को जाने की गारंटी है या नहीं । बंद करते समय संकेतों को अनदेखा करना एक अच्छा विचार हो सकता है।
तो यह प्रयास करें:
#!/bin/bash
trap 'killall' INT
killall() {
trap '' INT TERM # ignore INT and TERM while shutting down
echo "**** Shutting down... ****" # added double quotes
kill -TERM 0 # fixed order, send TERM not INT
wait
echo DONE
}
./process1 &
./process2 &
./process3 &
cat # wait forever