2015-08-27 5 views
15

उदाहरण के लिए redis आधिकारिक छवि में:डॉकर एंट्रीपॉइंट स्क्रिप्ट में निष्पादन का उपयोग करने का क्या उद्देश्य है?

https://github.com/docker-library/redis/blob/master/2.8/docker-entrypoint.sh

#!/bin/bash 
set -e 

if [ "$1" = 'redis-server' ]; then 
    chown -R redis . 
    exec gosu redis "[email protected]" 
fi 

exec "[email protected]" 

क्यों सिर्फ उन्हें पूर्ववर्ती कार्यकारी बिना हमेशा की तरह कमांड चलाने नहीं?

उत्तर

26

जैसा कि @ पीटर लाइन्स कहते हैं, निष्पादन का उपयोग करके दो प्रक्रियाओं की बजाय, मूल प्रक्रिया को प्रतिस्थापित कर दिया जाएगा।

डॉकर में यह सही है कि संकेतों को सही ढंग से प्रॉक्सी किया जाए। उदाहरण के लिए, यदि रेडिस को निष्पादित किए बिना शुरू किया गया था, तो उसे पर docker stop पर प्राप्त नहीं होगा और उसे साफ़ रूप से बंद करने का मौका नहीं मिलेगा। कुछ मामलों में, यह डेटा हानि या ज़ोंबी प्रक्रियाओं का कारण बन सकता है।

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

+0

डॉकर के संबंध में अतिरिक्त अंतर्दृष्टि के लिए धन्यवाद! – m0meni

+3

यह काफी महत्वपूर्ण है। – atamanroman

12

निष्पादन के बिना, माता-पिता खोल प्रक्रिया जीवित रहती है और बच्चे से बाहर निकलने की प्रतीक्षा करती है। निष्पादन के साथ, बाल प्रक्रिया पूरी तरह से पैरेंट प्रक्रिया को प्रतिस्थापित करती है, जब बच्चे को मारने के बाद माता-पिता के लिए कुछ भी नहीं होता है, तो मैं exec थोड़ा अधिक सटीक/सही/कुशल मानता हूं। चीजों की भव्य योजना में, मुझे लगता है कि इसे मामूली अनुकूलन के रूप में वर्गीकृत करना संभवतः सुरक्षित है।

कार्यकारी

  • माता पिता खोल बिना शुरू होता है
  • माता पिता खोल कांटे बच्चे
    • बच्चे
    • बच्चे बाहर निकालता है
  • माता पिता खोल बाहर निकलता है
  • चलाता है

कार्यकारी

  • माता पिता शेल के साथ शुरू होता है
  • माता पिता खोल कांटे बच्चे, बच्चे
  • बच्चे कार्यक्रम खोल की प्रक्रिया के ऊपर ले जा रन के साथ खुद को बदल देता है
  • बच्चे बाहर निकालता है
+0

तो आम तौर पर एक नया खोल बनाया जाएगा, लेकिन निष्पादन केवल इसे वर्तमान खोल में चलाने के लिए कहता है? – m0meni

+0

नहीं, केवल 1 खोल है, लेकिन बच्चे की प्रक्रिया को तोड़ने के बजाय, बच्चे से बाहर निकलने की प्रतीक्षा कर रहा है, और फिर "ओह देखो, मैं अपनी स्क्रिप्ट फ़ाइल के अंत में हूं और कुछ भी करने के लिए बाकी नहीं है", फिर बाहर निकलना, 'exec' संस्करण मूल रूप से पैरेंट खोल को" पूर्व-निकास "करता है, इसलिए जब बच्चा लेता है तो यह पहले से ही चला जाता है। हालांकि मुझे इस नृत्य के सटीक यांत्रिकी के रूप में गहरे यूनिक्स देवताओं को स्थगित करना होगा। –

+2

मुझे लगता है कि यह "मामूली अनुकूलन" से थोड़ा अधिक महत्वपूर्ण है, क्योंकि मूल प्रक्रिया सिग्नल को संभालने के लिए ज़िम्मेदार है। मैंने अपने जवाब में थोड़ा और लिखा है। –

2

इसे पूंछ रिकर्सन जैसे अनुकूलन के रूप में सोचें ।

यदि कोई अन्य प्रोग्राम चलाना शैल स्क्रिप्ट का अंतिम कार्य है, तो शेल को प्रोग्राम को नई प्रक्रिया में चलाने की आवश्यकता नहीं है और इसके लिए प्रतीक्षा करें। exec का उपयोग करके, खोल प्रक्रिया प्रोग्राम के साथ खुद को बदल देती है।

किसी भी मामले में, खोल स्क्रिप्ट का निकास मान समान होगा। जो भी प्रोग्राम मूल रूप से शेल स्क्रिप्ट कहलाता है उसे एक एक्जिट वैल्यू दिखाई देगा जो निष्पादित प्रोग्राम के बाहर निकलने वाले मूल्य के बराबर है (या 127 यदि प्रोग्राम नहीं मिल सकता है)।

मॉड्यूलो कोने के मामले जैसे प्रोग्राम अपने माता-पिता के नाम के आधार पर कुछ अलग कर रहा है।

संबंधित मुद्दे