क्या मैं एक बैश स्क्रिप्ट (.sh) फ़ाइल को संशोधित कर सकता हूँ जबकि वह चल रही है?


28

मान लीजिए मेरे पास एक स्क्रिप्ट है script.sh, जिसे निष्पादित करने में कुछ समय लगता है। मैं इसे निष्पादित करता हूं ./script.sh,। जबकि यह एक टर्मिनल विंडो में चल रहा है, मैं फ़ाइल को संशोधित करता हूं script.sh। क्या पहले से चल रही प्रक्रिया पर इसका कोई असर पड़ेगा?

इसे संशोधित करने के बाद, मैं संशोधित फ़ाइल निष्पादित करता हूं, इसलिए मेरे पास अभी दो चलने की प्रक्रिया है। यह ठीक है?


जवाबों:


36

जब आप अपनी स्क्रिप्ट में परिवर्तन करते हैं, तो आप डिस्क पर परिवर्तन करते हैं (हार्ड डिस्क- स्थायी भंडारण); जब आप स्क्रिप्ट निष्पादित करते हैं, तो स्क्रिप्ट आपकी मेमोरी (RAM) में लोड हो जाती है।

इसलिए, आप स्क्रिप्ट में जो परिवर्तन करते हैं, वह रनिंग स्क्रिप्ट को प्रभावित नहीं करेगा, यह उन परिवर्तनों को करने से पहले आपके द्वारा निष्पादित संस्करण को चलाएगा।

हालाँकि, जब आप पहले से चल रहे उदाहरण को समाप्त किए बिना परिवर्तित स्क्रिप्ट को फिर से निष्पादित करते हैं, तो स्क्रिप्ट के दो उदाहरण होंगे- एक जिसमें परिवर्तन और पुराना एक है।

चेतावनी दें कि स्क्रिप्ट का उपयोग और संशोधन करने वाले संसाधन संघर्ष करेंगे। उदाहरण के लिए, यदि आप स्क्रिप्ट का उपयोग करके किसी फ़ाइल को संशोधित कर रहे हैं, तो बाद में चलने वाली स्क्रिप्ट लिखने के लिए उस फ़ाइल को खोलने में सक्षम नहीं होगी और सही तरीके से निष्पादित नहीं हो पाएगी।

अद्यतन: Unix.stackexchange.com पर बेहतर उत्तर देने के लिए मुझे पंजीकृत उपयोगकर्ता के लिए धन्यवाद।

स्क्रिप्ट के आकार और प्रश्न में संकलक / व्याख्याकार के आधार पर, स्क्रिप्ट को आंशिक रूप से / पूरी तरह से लोड किया जाता है। इसलिए, यदि स्क्रिप्ट पूरी तरह से भरी हुई नहीं है, तो आपके द्वारा अपनी स्क्रिप्ट में किए गए परिवर्तन स्क्रिप्ट के भाग को मेमोरी में लोड होने के बाद चल रहे उदाहरण पर प्रतिबिंबित करेंगे।

इसलिए, डिस्क पर अपनी स्क्रिप्ट को बदलने की अनुशंसा नहीं की जाती है जो वर्तमान में अप्रत्याशित आउटपुट के लिए चल रही है: पहले चल रहे इंस्टेंस को रोकें और फिर अपनी स्क्रिप्ट को संशोधित करें और फिर स्क्रिप्ट को फिर से निष्पादित करें।



@registereduser: ओह हाँ, इस सवाल ने मुझे मेरे OS पाठों की याद दिला दी। जैसे ही मैं अपने डेस्कटॉप (मेरे फोन पर) पर अपने हाथ प्राप्त करता हूं, मेरे जवाब को संपादित कर दूंगा
जॉब

मेरा अनुमान है कि लघु लिपियों के लिए कोई समस्या नहीं होनी चाहिए।
बेको

1
जब मैंने इसे bash v3.2.48 ( यहाँ देखें ) के साथ आज़माया , तो यह पंक्ति के अंत से परे बफर नहीं किया (और जब मैं स्क्रिप्ट को निष्पादित करता हूं तो यह बुरी तरह से विफल हुआ)। मैं बस बैश v4.3.0 के साथ सेवानिवृत्त हुआ, और इसने पूरी (लघु) स्क्रिप्ट को बफ़र किया। इसलिए ... मैं किसी विशेष व्यवहार पर भरोसा नहीं करता।
गॉर्डन डेविसन

1
@RegisteredUser बैश के सभी संस्करणों के साथ नहीं - मेरे द्वारा जुड़ा उदाहरण देखें।
गॉर्डन डेविसन

4

मैं ऐसा कुछ जोड़ूंगा जो मुझे लगता है कि अन्य उत्तरों में नहीं कहा गया है। बहुत कुछ इस बात पर निर्भर करता है कि आप फ़ाइल को कैसे संपादित करते हैं। ऐसा करने से echo "stuff" >fileखोल (एक और उदाहरण) से वास्तव में फ़ाइल के ऊपर लिख देगा, मुझे लगता है। लेकिन अगर आप फ़ाइल को उदाहरण के लिए संपादित करते हैं emacsऔर फिर सहेजते हैं, तो ऐसा नहीं होगा। यहाँ के बजाय संपादक पुरानी फ़ाइल को कुछ बैकअप नाम (शायद वास्तव में पिछले बैकअप को हटा रहा है) का नाम बदल देता है, और फिर इसकी संशोधित बफर सामग्री को पुराने नाम के साथ एक नई फ़ाइल के रूप में लिखता है । चूंकि शेल (या अन्य दुभाषिया) स्क्रिप्ट पढ़ने के बाद निश्चित रूप से केवल एक बार ही फ़ाइल खोलेगी, उसके बाद यह फ़ाइल नाम के ठिकाने से स्वतंत्र है, यह सिर्फ भौतिक डिस्क फ़ाइल (इनोड संख्या द्वारा पहचाना गया) को पढ़ना जारी रखता है जो कि खोलने के समय फ़ाइल नाम से जुड़ा था। इसलिए भले ही यह स्क्रिप्ट को ब्लॉकों में पढ़ता है (जो कि बफ़र्ड टेक्स्ट I / O का उपयोग करते हुए सबसे आसान समाधान होगा), यह फ़ाइल के पुराने उदाहरण से लाइनें पढ़ना जारी रखेगा, जो आपके संपादन द्वारा नहीं बदलने की संभावना है।


+1 मैं अपने संपादक के रूप में उदात्त पाठ का उपयोग कर रहा हूं। क्या आपको पता है कि यह फ़ाइल का नाम बदल देता है, जैसे emacs?
बेको

1
मुझे लगता है कि अधिकांश संपादक नाम बदलने की योजना का उपयोग करेंगे (भले ही उन्हें बैकअप संस्करण नहीं रखना चाहिए) इस जोखिम से बचने के लिए कि यदि लेखन प्रक्रिया के दौरान कोई दुर्घटना हुई, तो पाठ का कोई भी बरकरार संस्करण बिल्कुल नहीं रहेगा। आप "ls -i" (जो इनोड संख्या दिखाता है) के साथ देख सकते हैं कि आपके संपादक का व्यवहार क्या है।
मार्क वैन लीउवेन जू

1

इसे अद्यतन करने की आवश्यकता है, उपरोक्त उत्तर अब केवल आंशिक रूप से सही हैं:

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

ऐसा करने का बेहतर तरीका यह है कि क्रियाओं का निम्नलिखित अनुक्रम है: 1) स्क्रिप्ट को मेमोरी में लोड करें 2) डिस्क से स्क्रिप्ट को हटाएं 3) डिस्क संस्करण को हटाकर डिस्क पर एक नई स्क्रिप्ट लिखें सबसे पहले, मेमोरी संस्करण इसके लिंक खो देता है ताकि जब आप चरण 3 में एक नया संस्करण प्रदान करते हैं, तो नई सामग्री को मेमोरी संस्करण में लोड करने के लिए बैश द्वारा कोई प्रयास नहीं किया जाएगा।


0

@ जॉबिन का उत्तर आमतौर पर सही होता है, लेकिन मैं कुछ अन्य उत्तर जोड़ूंगा जो उस बिंदु पर हो सकते हैं जो आप करना चाहते हैं।

यदि आप स्क्रिप्ट बदलना चाहते हैं, और यह जानना चाहते हैं कि यह सुरक्षित है, तो आप एक नई फ़ाइल में लिखना चाहते हैं, मौजूदा एक नहीं, नई फ़ाइल वह स्थित हो सकती है जहां पुरानी थी, हालांकि। अपने नए संस्करण को एक नई फ़ाइल में लिखें, और फिर mvपुराने के शीर्ष पर इसे स्थानांतरित करने के लिए उपयोग करें। जो फ़ाइल अभी भी बदली गई है, वह अभी मौजूद नहीं है, यह निर्देशिका से लिंक नहीं है। आपकी रनिंग स्क्रिप्ट इसका उपयोग करना जारी रख सकती है, और जब वह स्क्रिप्ट अपनी फ़ाइल को बंद कर देती है तो सिस्टम को पता चलता है कि यह सुरक्षित रूप से फ़ाइल को साफ कर सकता है (चाहे तुरंत या बाद में)।

यदि आप मक्खी पर स्क्रिप्ट का व्यवहार करना चाहते हैं, तो आपको अधिक कठिन समस्या है। मुझे उम्मीद है कि आपको इसे स्क्रिप्ट के कोड में बनाने की आवश्यकता होगी। बैश स्क्रिप्ट सिग्नल को संभाल सकती है (जैसे कुछ को पकड़ सकती है kill -USR1 [pid]), और एक स्क्रिप्ट फिर कुछ कोड को लोड करके जवाब दे सकती है। तो हो सकता है कि आप जो चाहते हैं उसके करीब कार्यक्षमता प्राप्त कर सकते हैं, लेकिन यह जानने के बिना कि आप क्या कर रहे हैं, मुझे ऐसा करने का एक अच्छा कारण नहीं दिखाई दे रहा है, और मुझे संदेह है कि यदि आप इस परिसर में कुछ करना चाहते हैं तो आप शायद अधिक परिष्कृत चाहते हैं इसमें करने के लिए प्रोग्रामिंग लैंग्वेज।

यदि आप किसी ऐसी स्क्रिप्ट के व्यवहार को हैक करना चाहते हैं, जो इसे ध्यान में रखकर नहीं लिखी गई है, तो आप भाग्य से बाहर हैं। मैं किसी भी प्रोग्रामिंग कार्य को असंभव कहने में संकोच करता हूं, लेकिन यदि आपके पास इस प्रकार के कार्य के लिए संसाधन और कौशल हैं, तो आप संभवतः यहां नहीं पूछेंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.