मुझे ps के लिए अलग निकास स्थिति क्यों मिलती है | एक स्क्रिप्ट में grep?


11

मैं स्क्रिप्ट के नीचे चल रहा हूं:

#!/bin/bash

ps ax  | grep -q [v]arnish
if [ $? -eq 0 ];then
        echo varnish is running...
        exit 0
else
        echo "Critical : varnish is not running "
        exit 2
fi

आउटपुट ::

[root@server ~]# sh -x check_varnish_pro.sh
+ ps ax
+ grep -q '[v]arnish'
+ '[' 0 -eq 0 ']'
+ echo varnish is running...
varnish is running...
+ exit 0

जब मैं कमांड लाइन में समान चलता हूं तो मुझे 1 के रूप में बाहर निकलने की स्थिति मिल रही है:

[root@server ~]# ps ax  | grep -q [v]arnish; echo $?
1

मामला ऐसा है जैसे सर्वर में वार्निश स्थापित नहीं है। यह स्क्रिप्ट एक सर्वर में ठीक काम करती है जहाँ वार्निश स्थापित है।

स्क्रिप्ट और कमांड लाइन का उपयोग करते समय अलग-अलग निकास स्थिति क्यों? इस लिपि को कैसे सुधारा जाए?


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

जवाबों:


10

जब आप check_varnish_pro.shपरीक्षण नामक एक स्क्रिप्ट चलाते हैं

ps ax  | grep -q [v]arnish

सफल है क्योंकि check_वार्निश नाम की एक स्क्रिप्ट _proचल रही है।


14

सामान्य तौर पर, यह एक बुरा विचार के साथ सरल दृष्टिकोण की कोशिश करने का है psऔर grepयदि किसी विशेष प्रक्रिया चल रहा है निर्धारित करने के लिए प्रयास करने के लिए।

इसके pgrepलिए उपयोग करने से आप बहुत बेहतर होंगे :

if pgrep "varnish" >/dev/null; then
  echo "Varnish in running"
else
  echo "Varnish is not running"
fi

के लिए मैनुअल देखें pgrep। कुछ प्रणालियों पर (शायद लिनक्स पर नहीं), आपको एक -qध्वज मिलता है जो उसी ध्वज से मेल खाता है grepजिसके लिए रीडायरेक्ट करने की आवश्यकता से छुटकारा मिलता है /dev/null। एक -fध्वज भी है जो केवल प्रक्रिया नाम पर होने के बजाय पूर्ण कमांड लाइन पर मैच करता है। एक मैच का उपयोग विशिष्ट उपयोगकर्ता से संबंधित प्रक्रियाओं तक सीमित कर सकता है -u

इंस्टॉल pgrepकरने से आपको एक्सेस भी मिलता है pkill, जिससे आप उनके नामों के आधार पर प्रक्रियाओं को संकेत दे सकते हैं।

इसके अलावा, अगर यह एक सेवा डेमॉन है , और यदि आपके यूनिक्स सिस्टम में इसे जानकारी के लिए क्वेरी करने का एक तरीका है (उदाहरण के लिए, यह ऊपर है और चल रहा है या नहीं), तो यह उस पर जाँच का उचित तरीका है।

लिनक्स पर, आपके पास systemctl( systemctl is-active --quiet varnishयदि यह चल रहा है, तो 0 वापस आ जाएगा), ओपनबीएसडी पर आपके पास rcctl, आदि।


अब आपकी स्क्रिप्ट पर:

आपकी स्क्रिप्ट में, आप आउटपुट से पार्स करते हैं ps ax। इस आउटपुट में स्क्रिप्ट का नाम ही होगा check_varnish_pro.sh, जिसमें स्पष्ट रूप से स्ट्रिंग शामिल है varnish। यह आपको एक झूठी सकारात्मक देता है। यदि आपने इसे बिना परीक्षण के -qलिए ध्वज के बिना चलाया था, तो आपने इसे देखा होगा grep

#!/bin/bash
ps ax | grep '[v]arnish'

इसे चलाना:

$ ./check_varnish_pro.sh
31004 p1  SN+     0:00.04 /bin/bash ./check_varnish_pro.sh

एक और मुद्दा यह है कि यद्यपि आप इस grepप्रक्रिया को "छिपाने" की कोशिश grepकरते [v]हैं कि पैटर्न का उपयोग करके स्वयं का पता लगाया जा सकता है । यदि आप स्क्रिप्ट या कमांड लाइन को निर्देशिका में चलाने के लिए होते हैं जो उस फ़ाइल या निर्देशिका में नामांकित है varnish, तो यह दृष्टिकोण विफल हो जाएगा (जिस स्थिति में आपको झूठी सकारात्मक मिलेगी, फिर से)। इसका कारण यह है कि पैटर्न unquoted है और शेल इसके साथ फ़ाइल नाम ग्लोबिंग प्रदर्शन करेगा।

देख:

bash-4.4$ set -x
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep '[v]arnish'
bash-4.4$ touch varnish
+ touch varnish
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep varnish
91829 p2  SN+p    0:00.02 grep varnish

फ़ाइल की उपस्थिति varnishशेल को [v]arnishफ़ाइल नाम के साथ बदलने का कारण बनेगी varnishऔर आपको प्रक्रिया तालिका ( grepप्रक्रिया) में पैटर्न पर एक हिट मिलेगी ।


4
क्योंकि सब कुछ एक फाइल है "लिनक्स भूमि में"।
ज़ी

@ z_- यह सुनिश्चित नहीं है कि यह कैसे जुड़ा हुआ है, लेकिन यह गैर-लिनक्स यूनियनों पर भी सही है।
Kusalananda

4
न केवल grep प्रक्रिया; स्क्रिप्ट का नाम check_varnish_pro.shभी एक कारक है।
टीएनडब्ल्यू

@TNW मैं पहली बार में हाजिर नहीं था, लेकिन आप सही हैं। मैं में है कि जोड़ देंगे।
Kusalananda

3

@AlexP वास्तव में क्या हो रहा है, बहुत स्पष्ट रूप से समझाती है , लेकिन @ कुसलानंद का एक महत्वपूर्ण प्रक्रिया के लिए उपयोग करनेpgreppkill का विचार / दृढ़ता से हतोत्साहित किया जाता हैबेहतर समाधानों में शामिल हैं:

  • सेवा से पूछ रहा है कि क्या चल रहा है। systemctl status varnishdएक आधुनिक * निक्स इंस्टॉलेशन पर इसका ध्यान रखना चाहिए।
  • यदि कुछ दुर्भाग्यपूर्ण परिस्थितियों में आपके पास कोई सेवा उपलब्ध नहीं है, तो आप प्रक्रिया शुरू होते ही समस्या की रिपोर्ट करने के लिए स्टार्टअप स्क्रिप्ट को बदल सकते हैं:

    varnish || true
    some_command_to_send_an_alert_that_the_service_has_died
    
  • वैकल्पिक रूप से उस स्क्रिप्ट को बदलें जो पीआईडी को रिकॉर्ड करने के लिए सेवा शुरू करती है , और फिर समय-समय पर राज्य की जांच करें kill -0 "$pid"

मैं सहमत हूं, मैं समस्या के शेल स्क्रिप्टिंग पहलुओं को संबोधित कर रहा था। ध्यान दें कि systemctlलगभग केवल लिनक्स (AFAIK) पर उपलब्ध है, और सभी आधुनिक यूनिक्स जैसी प्रणालियों पर नहीं।
Kusalananda

मूल प्रश्न का टैग "linux" था; मुझे यकीन नहीं है कि क्यों @ muru द्वारा हटा दिया गया था।
l0b0

धन्यवाद l0b0 मेरे दो प्रश्न थे "क्यों" और "सुधार कैसे करें"। @ एलेक्सपी के जवाब ने मेरा पहला सवाल हल कर दिया और दूसरे सवाल के लिए आपका जवाब बेहतर है। लेकिन कुसलानंद इससे जुड़ी बातें बताते हैं जो मुझे लगता है कि उन लोगों के लिए मददगार होगी जिनके पास इसी तरह के मुद्दे हैं। इसलिए मैं अब उलझन में हूं कि मुझे उत्तर के रूप में किसे स्वीकार करना चाहिए।
प्रादो

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