शेल स्क्रिप्ट को संपादित करें जब वह चल रहा हो


91

क्या आप एक शेल स्क्रिप्ट को संपादित कर सकते हैं, जबकि यह चल रही है और बदलावों से रनिंग स्क्रिप्ट प्रभावित होती है?

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

यदि संभव नहीं है, तो क्या कोई शेल या बैच-तंत्र है जो मुझे ऐसा करने की अनुमति देगा?

बेशक, मैंने इसे आज़माया है, लेकिन यह देखने से पहले कि यह काम किया है या नहीं, यह घंटों का होगा और मैं उत्सुक हूं कि पर्दे के पीछे क्या हो रहा है या नहीं हो रहा है।


1
मैंने रनिंग स्क्रिप्ट के लिए स्क्रिप्ट फ़ाइल को संपादित करने से दो परिणाम देखे हैं: 1) परिवर्तनों को अनदेखा किया जाता है जैसे कि उसने पूरी चीज़ को मेमोरी में पढ़ा है या 2) स्क्रिप्ट एक त्रुटि के साथ क्रैश हो जाती है जैसे कि यह कमांड का हिस्सा पढ़ा था। मुझे नहीं पता कि यह स्क्रिप्ट के आकार पर निर्भर है। किसी भी तरह से, मैं यह कोशिश नहीं करेगा।
पॉल टॉम्बलिन

संक्षेप में: नहीं, जब तक कि यह स्वयं-संदर्भित / कॉलिंग न हो, जिस स्थिति में मुख्य स्क्रिप्ट अभी भी पुरानी होगी।
15

यहां दो महत्वपूर्ण प्रश्न हैं। 1) मैं सही और सुरक्षित रूप से कमांड को एक स्क्रिप्ट में कैसे जोड़ सकता हूं? 2) जब मैं एक रनिंग स्क्रिप्ट को संशोधित करता हूं, तो क्या होगा?
क्रिस क्नेनेल

3
सवाल यह है कि क्या कोई शेल किसी स्क्रिप्ट को पूरी स्क्रिप्ट फ़ाइल को पढ़कर निष्पादित करता है और फिर इसे निष्पादित करता है, या इसे निष्पादित करते हुए आंशिक रूप से पढ़ता है। मुझे नहीं पता कि यह कौन सा है; यह भी निर्दिष्ट नहीं किया जा सकता है। आपको व्यवहार के आधार पर बचना चाहिए।
कीथ थॉम्पसन

जवाबों:


-67

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

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


66
मैंने इसके विपरीत देखा है। संपादित की जा रही चलने वाली स्क्रिप्ट को चलाने की स्क्रिप्ट को क्रैश करने का कारण बन सकता है क्योंकि फ़ाइल को bash की स्क्रिप्ट रीडिंग फ़ाइल स्थिति के अंतर्गत ले जाती है।
तिलमन वोगेल

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

6
यह निश्चित रूप से ऑन-डिस्क फ़ाइल से स्वतंत्र नहीं है । शेल आमतौर पर ब्लॉक में स्क्रिप्ट पढ़ता है, उदाहरण के लिए, 128 बाइट्स या 4096 बाइट्स या 16384 बाइट्स, और केवल अगले ब्लॉक को पढ़ता है जब इसे नए इनपुट की आवश्यकता होती है। (आप स्क्रिप्ट चलाने वाले शेल पर lsof जैसी चीजें कर सकते हैं और देखें कि यह अभी भी फ़ाइल खोली गई है।)
mirabilos

5
वास्तव में यदि आप किसी स्क्रिप्ट को संपादित करते हैं तो यह प्रक्रिया के विफल होने का कारण बनता है।
एरिक क्रोनिटी

8
आप सही नहीं हैं। यह कार्यान्वयन के आधार पर बफ़र किया जाता है और स्क्रिप्ट में वास्तविक कमांड को कॉल किया जा रहा है, चाहे stdout को किसी फ़ाइल में रीडायरेक्ट किया गया हो, कई कारक हैं और आपका उत्तर बस सही नहीं है।
GL2014

50

यह कम से कम मेरे वातावरण में, लेकिन बहुत अप्रिय तरीके से प्रभावित करता है । ये कोड देखें। पहला :a.sh

#!/bin/sh

echo "First echo"
read y

echo "$y"

echo "That's all."

b.sh:

#!/bin/sh

echo "First echo"
read y

echo "Inserted"

echo "$y"

# echo "That's all."

करना

$ cp a.sh run.sh
$ ./run.sh
$ # open another terminal
$ cp b.sh run.sh  # while 'read' is in effect
$ # Then type "hello."

मेरे मामले में, आउटपुट हमेशा होता है:

हैलो
हैलो
बस इतना ही।
बस इतना ही।

(बेशक यह इसे स्वचालित करने के लिए बेहतर है, लेकिन उपरोक्त उदाहरण पठनीय है।)

[संपादित करें] यह अप्रत्याशित है, इस प्रकार खतरनाक है। सबसे अच्छा वर्कअराउंड है , जैसा कि यहां बताया गया है कि सभी को एक ब्रेस में रखा गया है, और समापन ब्रेस से पहले, "बाहर निकलें" डाल दियाजुड़े जवाब को अच्छी तरह से पढ़ें ताकि नुकसान से बचा जा सके।

] "रीड" लाइन।


3
Mh, मैं स्नेह नहीं देखता। क्या मैं कुछ भूल रहा हूँ?
उपयोगकर्ता अज्ञात

सटीक व्यवहार एक अतिरिक्त न्यूलाइन पर निर्भर करता है , और शायद यूनिक्स स्वाद, फाइलसिस्टम आदि पर भी, अल पर यकीन नहीं है। यदि आप किसी भी प्रभाव को देखना चाहते हैं, तो बस b.shइको फू / बार / बाज की 10 लाइनें जोड़कर विस्तार करें । Dave4220 और मेरे द्वारा दिए गए उत्तरों का सार यह है कि प्रभाव की भविष्यवाणी करना आसान नहीं है। (BTW संज्ञा "स्नेह" का अर्थ है "प्रेम" =)
तैका काज़ुरा

हाँ, यह बहुत टूट गया है। मेरे पास एक समाधान है (नीचे)। क्या और भी खतरनाक है svn / rsync / git अपडेट
एरिक एरोनिटी

39

इसे आज़माएं ... नामक एक फ़ाइल बनाएँ bash-is-odd.sh:

#!/bin/bash
echo "echo yes i do odd things" >> bash-is-odd.sh

यह दर्शाता है कि बैश है, वास्तव में, स्क्रिप्ट की व्याख्या "जैसा कि आप जाते हैं"। वास्तव में, लंबे समय तक चलने वाली स्क्रिप्ट के संपादन में अप्रत्याशित परिणाम होते हैं, यादृच्छिक वर्णों को सम्मिलित करना आदि क्यों? क्योंकि बैश अंतिम बाइट स्थिति से पढ़ता है, इसलिए संपादन वर्तमान चरित्र के स्थान को पढ़ा जा रहा है।

बैश एक शब्द में है, बहुत, बहुत असुरक्षित इस "सुविधा" के कारण। sv और rsyncजब bash लिपियों के साथ प्रयोग किया जाता है तो वे विशेष रूप से परेशान होते हैं, क्योंकि डिफ़ॉल्ट रूप से वे परिणामों को "मर्ज" करते हैं ... जगह में संपादन करते हैं। rsyncएक विधा है जो इसे ठीक करती है। svn और git नहीं।

मैं एक समाधान प्रस्तुत करता हूं। नामक एक फ़ाइल बनाएँ /bin/bashx:

#!/bin/bash
source "$1"

अब #!/bin/bashxअपनी लिपियों पर प्रयोग करें और हमेशा bashxइसके बजाय उन्हें चलाएं bash। यह समस्या को हल करता है - आप rsyncअपनी स्क्रिप्ट सुरक्षित रूप से कर सकते हैं ।

वैकल्पिक (इन-लाइन) समाधान प्रस्तावित / AF AF द्वारा:

{
   # your script
} 
exit $?

घुंघराले ब्रेसिट एडिट्स से बचाते हैं, और एग्जिट एपेंड्स से बचाते हैं। बेशक, हम सभी को बहुत बेहतर होगा अगर बैश एक विकल्प के साथ आया, जैसे -w(संपूर्ण फ़ाइल), या ऐसा कुछ जिसने ऐसा किया।


1
btw; माइनस का मुकाबला करने के लिए यहां एक प्लस है और क्योंकि मुझे आपका संपादित उत्तर पसंद है।
एंड्रयू बार्बर

1
मैं इसकी सिफारिश नहीं कर सकता। इस वर्कअराउंड में, स्थितिगत मापदंडों को एक से स्थानांतरित कर दिया जाता है। यह भी याद रखें कि आप $ 0 के लिए मान निर्दिष्ट नहीं कर सकते हैं। इसका मतलब यह है कि यदि आप बस "/ बिन / बैश" को "/ बिन / बैशक्स" में बदलते हैं, तो कई स्क्रिप्ट विफल हो जाती हैं।
टेकिका कजुरा

1
कृपया मुझे बताएं कि ऐसा विकल्प पहले ही लागू किया जा चुका है!
AF7

10
एक सरल उपाय, मेरे मित्र Giulio (क्रेडिट जहां कारण है) द्वारा मुझे सुझाव दिया गया है कि वह शुरुआत में {और} स्क्रिट के अंत में डालें। बैश को स्मृति में सब कुछ पढ़ने के लिए मजबूर किया जाता है।
AF7

1
@ AF7 अपने दोस्त के समाधान पर सुधार कर रहा है: {your_code; } && बाहर जाएं; के रूप में अच्छी तरह से क्रियान्वित किया जा रहा से अंत तक जुड़ी लाइनों को रोकने जाएगा।
कॉर्कमैन

17

अपनी स्क्रिप्ट को फ़ंक्शन में तोड़ें, और हर बार एक फ़ंक्शन को आपको sourceएक अलग फ़ाइल से बुलाया जाता है । फिर आप किसी भी समय फ़ाइलों को संपादित कर सकते हैं और आपकी रनिंग स्क्रिप्ट अगली बार इसमें परिवर्तन हो जाएगी।

foo() {
  source foo.sh
}
foo

मैं इस तकनीक का उपयोग कुछ समय से प्रभावी रूप से अपनी लंबी चलने वाली बिल्ड स्क्रिप्ट को अपडेट करने के लिए कर रहा हूं, जबकि वे चल रहे हैं। मुझे वर्तमान फ़ाइल को फ़ाइल के अंत तक पढ़ने के लिए एक तकनीक सीखने में खुशी होगी, ताकि मुझे अपनी शेल स्क्रिप्ट को लागू करने के लिए दो फाइलें न हों।
क्रिस क्नेनेल

3

अच्छा प्रश्न! आशा है कि यह सरल स्क्रिप्ट मदद करती है

#!/bin/sh
echo "Waiting..."
echo "echo \"Success! Edits to a .sh while it executes do affect the executing script! I added this line to myself during execution\"  " >> ${0}
sleep 5
echo "When I was run, this was the last line"

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


2

एक दिलचस्प पक्ष नोट - यदि आप पायथन स्क्रिप्ट चला रहे हैं तो यह नहीं बदलता है। (यह संभवतः किसी के लिए स्पष्ट रूप से स्पष्ट है जो समझता है कि शेल पायथन स्क्रिप्ट कैसे चलाता है, लेकिन यह किसी को इस कार्यक्षमता की तलाश में एक उपयोगी अनुस्मारक हो सकता है।)

मैंने बनाया:

#!/usr/bin/env python3
import time
print('Starts')
time.sleep(10)
print('Finishes unchanged')

फिर एक और खोल में, जबकि यह सो रहा है, अंतिम पंक्ति को संपादित करें। जब यह पूरा हो जाता है तो यह अनकल्ड लाइन प्रदर्शित करता है, संभवतः क्योंकि यह चल रहा है .pyc? उबंटू और मैकओएस पर भी ऐसा ही होता है।


1

मैं csh स्थापित नहीं है, लेकिन

#!/bin/sh
echo Waiting...
sleep 60
echo Change didn't happen

उसे चलाएं, पढ़ने के लिए अंतिम पंक्ति को जल्दी से संपादित करें

echo Change happened

आउटपुट है

Waiting...
/home/dave/tmp/change.sh: 4: Syntax error: Unterminated quoted string

Hrmph।

मुझे लगता है कि शेल स्क्रिप्ट्स के संपादन तब तक प्रभावी नहीं होते जब तक वे पुनर्मिलन नहीं करते।


2
आपको वह स्ट्रिंग रखनी चाहिए जिसे आप उद्धरणों में प्रदर्शित करना चाहते हैं।
user1463308

2
वास्तव में, यह साबित करता है कि आपका संपादक आपके सोचने के तरीके पर काम नहीं करता है। कई, कई संपादक (vim, emacs सहित) एक "tmp" फ़ाइल पर काम करते हैं, और लाइव फ़ाइल नहीं। Vi / emacs के बजाय "इको 'इको उह ओह' >> myshell.sh" का उपयोग करने का प्रयास करें ... और देखें कि यह नया सामान आउटपुट करता है। इससे भी बदतर ... svn और rsync भी इस तरह से संपादित करते हैं!
एरिक एरोनिटी

3
-1। यह त्रुटि संपादित की जा रही फ़ाइल से संबंधित नहीं है: ऐसा इसलिए है क्योंकि आप एपोस्ट्रोफ़ का उपयोग कर रहे हैं! यह एक एकल उद्धरण के रूप में कार्य करता है, जिससे त्रुटि होती है। उस पूरे स्ट्रिंग को डबल कोट्स में रखें और फिर से कोशिश करें।
बेनामी पेंगुइन

5
तथ्य यह है कि त्रुटि हुई पता चलता है कि संपादित करने का इरादा प्रभाव नहीं था।
डैनकार्ड

@danmcardle कौन जानता है? शायद बैश देखा Change didn'ned
किरिल ब्यूलगिन

1

यदि यह सब एक ही स्क्रिप्ट में है, तो नहीं यह काम नहीं करेगा। हालाँकि, यदि आप इसे उप-स्क्रिप्ट्स को कॉल करने वाली ड्राइवर स्क्रिप्ट के रूप में सेट करते हैं, तो आप इसे कॉल करने से पहले एक सब-स्क्रिप्ट को बदलने में सक्षम हो सकते हैं, या इससे पहले कि इसे दोबारा कॉल किया जाए यदि आप लूपिंग कर रहे हैं, और उस स्थिति में मेरा मानना ​​है कि उन परिवर्तनों को निष्पादन में परिलक्षित होगा।


0

मैं सुन रहा हूँ न ... लेकिन कुछ परोक्ष के बारे में क्या

BatchRunner.sh

Command1.sh
Command2.sh

Command1.sh

runSomething

Command2.sh

runSomethingElse

तब आपको बैच कमांडर को सही होने से पहले प्रत्येक कमांड फ़ाइल की सामग्री को संपादित करने में सक्षम होना चाहिए?

या

एक क्लीनर संस्करण में BatchRunner का एक ही फाइल पर ध्यान होगा, जहाँ यह एक समय में लगातार एक लाइन चलाएगा। तब आपको इस दूसरी फ़ाइल को संपादित करने में सक्षम होना चाहिए, जबकि पहला सही चल रहा है?


मुझे आश्चर्य है कि अगर यह उन्हें चलाने के लिए स्मृति में लोड करता है और मुख्य प्रक्रिया शुरू होने के बाद एक बदलाव मायने नहीं रखता है ...
एरिक होडोंस्की

0

अपनी स्क्रिप्टिंग के बजाय Zsh का उपयोग करें।

AFAICT, Zsh इस निराशाजनक व्यवहार को प्रदर्शित नहीं करता है।


यह कारण है # 473, जोश को कोसना पसंद करता है। मैं हाल ही में एक पुरानी बैश स्क्रिप्ट पर काम कर रहा हूं, जिसे चलाने के लिए 10 मीटर का समय लगता है, और मैं इसे पूरा करने की प्रतीक्षा करते हुए इसे संपादित नहीं कर सकता!
मीका इलियट

-5

आमतौर पर, अपनी स्क्रिप्ट को संपादित करते समय यह असामान्य है। आपको बस इतना करना है कि अपने ऑपरेशनों के लिए कंट्रोल चेक करें। शर्तों के लिए जाँच करने के लिए यदि / अन्यथा कथन का उपयोग करें। अगर कुछ विफल होता है, तो यह करो, बाकी ऐसा करो। यही रास्ता तय करना है।


यह वास्तव में स्क्रिप्ट के बारे में कम है, क्योंकि यह बैच जॉब मिड ऑपरेशन को संशोधित करने का निर्णय ले रहा है। IE मुझे एहसास है कि मैं और अधिक संकलन करना चाहता हूं, या यह कि मुझे कतार में पहले से ही कुछ नौकरियों की आवश्यकता नहीं है।
पावती

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