2010-07-21 9 views
5

मैंने चारों ओर खोज की है लेकिन मुझे जो कुछ भी मिल रहा है वह काफी नहीं मिला है। संक्षेप में मैंने एक अनंत चलने के दौरान एक बैश स्क्रिप्ट बनाई है, जबकि लूप, सो रहा है और जांच रहा है कि कोई प्रक्रिया चल रही है या नहीं। एकमात्र समस्या यह है कि प्रक्रिया चल रही है, लेकिन यह कहता है कि यह एक और उदाहरण नहीं है।किसी प्रोग्राम की निगरानी के लिए शेल स्क्रिप्ट का उपयोग कैसे करें?

मुझे पता है कि मुझे प्रक्रिया के नाम से जांच करनी चाहिए और आईडी की प्रक्रिया नहीं करनी चाहिए, क्योंकि एक और प्रक्रिया कूद सकती है और आईडी ले सकती है। हालांकि सभी perl कार्यक्रमों को मेरे सिस्टम पर Perl5.10.0 नाम दिया गया है, और मैं एक ही पर्ल कार्यक्रम के कई उदाहरण खोलने का इरादा रखता हूं।

निम्नलिखित "अगर" हमेशा झूठा लौटाता है, तो मैं यहां क्या गलत कर रहा हूं ???

while true; do 

if [ ps -p $pid ]; then 
    echo "Program running fine" 
    sleep 10 

else 
    echo "Program being restarted\n" 
    perl program_name.pl & 
    sleep 5 
    read -r pid < "${filename}_pid.txt" 
fi 

done 

उत्तर

9

वर्ग ब्रैकेट से छुटकारा पाएं। यह होना चाहिए:

if ps -p $pid; then 

वर्ग कोष्ठक test आदेश के लिए वाक्यात्मक चीनी हैं। यह एक बिल्कुल अलग जानवर है और सब पर ps आह्वान नहीं करता है:

if test ps -p $pid; then 

वास्तव में पैदावार है कि "-bash: [: -p: द्विआधारी ऑपरेटर की उम्मीद" जब मैं इसे चलाने के।

+0

बहुत बढ़िया, मैंने आज शैल स्क्रिप्टिंग शुरू कर दी और यह मुझे पागल कर रहा था। मैं किसी भी दिन किसी भी दिन जटिल रूप से जटिल पर एक सरल वाक्यविन्यास मुद्दा ले जाऊंगा। एक बार फिर धन्यवाद। पीएस: आपने इतनी जल्दी उत्तर दिया (मैंने पोस्ट किया, बाथरूम में गया, और एक समाधान पर वापस आ गया लव लव ओवर!) कि मुझे अपने उत्तर को सही के रूप में जांचने के लिए इंतजार करना है, लेकिन मैं थोड़ी देर में रहूंगा। – user387049

+0

@ user387049: जॉन कुगलमैन का जवाब आपके खोल ज्ञान के लिए अच्छा है। हालांकि आपकी स्क्रिप्ट एक कार्यक्रम की निगरानी का एक खराब तरीका है; [एमएसडब्ल्यू का जवाब] (http://stackoverflow.com/questions/3304559/how-to-use-a-shell-script-to-supervise-a-faulty-program/3304634#3304634) बताते हैं क्यों। एक मौजूदा पर्यवेक्षक कार्यक्रम का उपयोग करना एक और अधिक मजबूत समाधान होगा, जैसे कि [जोनास] (http://stackoverflow.com/questions/3304559/how-to-use-a-shell-script-to- निगरानी एक दोषपूर्ण-कार्यक्रम/3306727 # 3306727)। – Gilles

0

यही है कि हत्या -0 $ पिड है। यदि पीआईडी ​​$ pid के साथ एक प्रक्रिया मौजूद है तो यह सफलता प्राप्त करता है।

+0

उस आदेश के साथ समस्या यह है कि आप केवल उन प्रक्रियाओं की जांच कर सकते हैं जो आपके उपयोगकर्ता से उत्पन्न हैं, जो स्क्रिप्ट चलाते हैं। – Anders

+1

@Anders: यदि आपकी स्क्रिप्ट प्रक्रिया को पुनरारंभ करने के लिए भी ज़िम्मेदार है (जैसा उपरोक्त उदाहरण में है), तो यह एक उचित धारणा है। –

7

सिंटैक्स त्रुटि के अलावा पहले से ही इंगित किया गया है, यह सुनिश्चित करने का एक लुभावना तरीका है कि एक प्रक्रिया जिंदा रहती है।

सबसे पहले, आपको पता होना चाहिए कि आपका प्रोग्राम पहले स्थान पर क्यों मर रहा है; यह स्क्रिप्ट एक बग ठीक नहीं करता है, यह एक को छिपाने की कोशिश करता है।

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

टिप्पणी करने के लिए जवाब में कहा:

ज़रूर, वहाँ इंजीनियरिंग मजबूरियों हैं, लेकिन के रूप में ओ पी ओ पी में बताया गया है, वहाँ अभी भी एक समाधान पर इस प्रयास में एक बग है:

मुझे पता है कि मुझे प्रक्रिया नाम द्वारा जांचना चाहिए और आईडी को संसाधित नहीं करना चाहिए, क्योंकि प्रक्रिया कूद सकती है और आईडी ले सकती है।

तो अब आपको एक पीआईडी ​​ट्रैकिंग स्क्रिप्ट के साथ छोड़ दिया गया है, न कि प्रक्रिया "नानी"।हालांकि संभावना है कि छोटे हैं, स्क्रिप्ट अब यह खड़ा के रूप में एक दस दूसरा खिड़की जिसमें

  1. "नजर रखी" प्रक्रिया विफल
  2. मैं अपने सप्ताह भर चलने Emacs प्रक्रिया है जो एक ही पीआईडी ​​
  3. पकड़ लेता है शुरू किया है नानी स्क्रिप्ट इस बात से अनजान है कि इसका आश्रित

स्क्रिप्ट केवल छोटी नहीं है, यह अमान्य है क्योंकि यह मानता है कि पीआईडी ​​एक प्रक्रिया के स्थिर पहचानकर्ता हैं। ऐसे तरीके हैं जिन्हें शैल स्क्रिप्ट स्तर पर भी बेहतर तरीके से संभाला जा सकता है। सबसे आसान यह है कि स्क्रिप्ट से perl के निष्पादन को कभी भी अलग न करें क्योंकि स्क्रिप्ट सबप्रोसेस देखने के अलावा कुछ और नहीं कर रही है। उदाहरण के लिए:

while true ; do 
    if perl program_name.pl ; then 
     echo "program_name terminated normally, restarting" 
    else 
     echo "oops program_name died again, restarting" 
    fi 
done 

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

+0

सबसे पहले, कोई समस्या का कारण हमेशा ठीक नहीं कर सकता क्योंकि यह हाथों से बाहर है। दूसरा, मैं सहमत हूं, हालांकि, एक अच्छी तरह से डिज़ाइन की गई स्क्रिप्ट आसानी से "बग्गी" के बिना इस तरह के कार्यों को निष्पादित कर सकती है। लेकिन हां, अगर मौजूदा है तो हमेशा मौजूदा कार्यक्षमता का उपयोग करना चाहिए। – Anders

+0

अंतर्निहित समस्या को ठीक करने के दौरान सबसे अच्छा होगा, यह एक आसान और अधिक स्थिर मार्ग की तरह लग रहा था। पर्ल से जो त्रुटियां मिल रही हैं वे या तो सेगमेंटेशन दोष हैं, असंगत रूप से गुंजाइश छोड़ रहे हैं, या साझा चर को संपादित कर रहे हैं। अब ये त्रुटियां स्वयं असंगत हैं, भले ही मैं प्रोग्राम को बैक अप शुरू करता हूं और उसी इनपुट फ़ाइल को चलाता हूं, मुझे कोई त्रुटि नहीं मिल सकती है। इसके अलावा मेरी शेल स्क्रिप्ट अब भी बदबूदार नहीं है, यह केवल यही मुद्दा था इसलिए मैं पूरी तरह से काम करने की अपेक्षा करता हूं। – user387049

+0

@ user387049: यह अभी भी छोटी है, ऊपर "मेरे" जोड़ा गया देखें। – msw

3

मैं पूरी तरह से सहमत हूं कि पीआईडी ​​के साथ झुकाव लगभग हमेशा एक बुरा विचार है। while true ; do ... done स्क्रिप्ट काफी अच्छी है, हालांकि उत्पादन प्रणालियों के लिए वहां कुछ प्रक्रिया पर्यवेक्षकों हैं जो वास्तव में यह और बहुत कुछ करते हैं, उदा।

  • जांच कितनी देर तक एक सेवा अप किया गया है या नीचे
  • कब्जा इसके उत्पादन (यह पीआईडी ​​है जानने के बिना) निगरानी प्रक्रिया को संकेत भेजते हैं और यह एक लॉग फ़ाइल में लिखने के लिए सक्षम

ऐसी प्रक्रिया पर्यवेक्षकों के उदाहरण daemontools या runit हैं। अधिक विस्तृत चर्चा और उदाहरणों के लिए Init scripts considered harmful देखें। शीर्षक से परेशान न हों: पारंपरिक इनिट स्क्रिप्ट्स वही समस्या से पीड़ित हैं जैसे आप करते हैं (वे एक डिमन शुरू करते हैं, इसे फ़ाइल में पीआईडी ​​रखें और फिर अकेले डिमन छोड़ दें)।

1

मैं मानता हूं कि आपको पता होना चाहिए कि आपका प्रोग्राम पहले स्थान पर क्यों मर रहा है। हालांकि, एक चल रही खोल स्क्रिप्ट शायद एक अच्छा विचार नहीं है। क्या होगा अगर यह पर्यवेक्षण खोल स्क्रिप्ट मर जाए? (। और हाँ, ps -p $pid चारों ओर वर्ग कोष्ठकों से छुटकारा पाने के लिए आप ps -p $pid आदेश के निकास स्थिति चाहते वर्ग कोष्ठक test आदेश के लिए एक स्थानापन्न कर रहे हैं।।)

दो संभव समाधान कर रहे हैं:

  1. अपनी "पर्यवेक्षण" खोल स्क्रिप्ट चलाने के लिए क्रॉन का उपयोग यह देखने के लिए करें कि आप जिस प्रक्रिया की निगरानी कर रहे हैं वह अभी भी चल रहा है, और यदि ऐसा नहीं है, तो इसे पुनरारंभ करें। पर्यवेक्षित प्रक्रिया इसकी पीआईडी ​​को फाइल में आउटपुट कर सकती है। आपका पर्यवेक्षण कार्यक्रम तब इस फ़ाइल को बिल्ली दे सकता है और पीआईडी ​​को जांचने के लिए प्राप्त कर सकता है।

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

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