बैश स्क्रिप्ट त्रुटि: पूर्णांक अभिव्यक्ति अपेक्षित


13

मैं एक अजीब समस्या है, मैं कई सर्वरों पर एक स्क्रिप्ट (बैश) चला रहा हूं और यह एक सर्वर पर काम करना बंद कर देता है (अन्य सभी सर्वरों पर पूरी तरह से ठीक काम करता है)।

यहाँ स्क्रिप्ट का समस्या भाग है: (मैंने इसे स्वयं नहीं लिखा था, सभी क्रेडिट "रिच" में जाते हैं) ( http://www.notrainers.org/monitoring-memory-usage-on-linux-with-nagios- और- nrpe / )

    if [ "$result" -lt "$warn_level" ]; then     #Line 56
    echo "Memory OK. $result% used."
    exit 0;
elif [ "$result" -ge "$warn_level" ] && [ "$result" -le "$critical_level" ]; then  #Line 59
    echo "Memory WARNING. $result% used."
    exit 1;
elif [ "$result" -gt "$critical_level" ]; then   #Line 62
    echo "Memory CRITICAL. $result% used."
    exit 2;
fi

पूर्ण त्रुटि संदेश:

./check_memory.sh: Line 56: [: 7.: integer expression expected

./check_memory.sh: Line 59: [: 7.: integer expression expected

./check_memory.sh: Line 62: [: 7.: integer expression expected

यदि आपको अधिक जानकारी की आवश्यकता है, तो मुझे बताएं और मैं इसे जितनी जल्दी हो सके आपूर्ति करने का प्रयास करूंगा।

सभी इनपुटों की सराहना करें :)

जवाबों:


5

आपके द्वारा दिए गए लिंक से, मैं नीचे की रेखा देखता हूं।

result=$(echo "$used / $total * 100" |bc -l|cut -c -2)

@ ग्रीम की टिप्पणी के अनुसार, उपरोक्त पंक्ति को नीचे बदलें।

result=$(echo "$used / $total * 100" |bc -l)

अब, उपरोक्त पंक्ति को जोड़ने के बाद, हमें resultपूर्णांक के आउटपुट को नीचे के रूप में बदलना होगा ।

result1=${result/.*}

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

result1=${result/.*}

और resultचर नामों को छोरों के result1अंदर बदलने के बजाय if, और त्रुटि उत्पन्न नहीं होगी।

मुझे संदेह है, cut -c -2त्रुटि के लिए विशेषताएँ क्योंकि यह केवल पहले 2 वर्णों को काट रहा है। क्या होगा अगर परिणाम में सिर्फ एक चरित्र है? मान लीजिए कि यदि परिणाम है 1.23456, तो उपरोक्त कटौती के परिणामस्वरूप 1.मूल्य होगा resultजिसके लिए स्पष्ट रूप से integer expectedत्रुटि का कारण है ।

शेष सर्वरों में यह ठीक काम कर रहा है, क्योंकि इसने एक ऐसे मामले का सामना नहीं किया है जहां resultचर का केवल एक अंक है। शेष सर्वरों में भी असफल होने की बहुत अधिक संभावना है, यदि परिणाम एकल अंक चर है (जैसा कि मैंने ऊपर उदाहरण में उल्लेख किया है)।


${result%%.*}यहाँ दशमलव बिंदु को हटाने के लिए सही विस्तार होगा। लेकिन ध्यान दें कि cut -c -2वसीयत 100 या अधिक की संख्या के साथ भी मुद्दों का कारण बनेगी, इसलिए इसे पूरी तरह से छोड़ देना सुरक्षित है।
ग्रीम

@Graeme, मुझे वह याद आया। मुझे उस लाइन में बदलाव करना चाहिए था :)
रमेश

6

चीजों की नज़र से, आपके resultचर .में यह है कि नंबर बनाने के बाद बैश इसे इस तरह से नहीं पहचाना जाता है। आप बस करके त्रुटि को पुन: उत्पन्न कर सकते हैं:

[ 7. -gt 1 ]

यदि आप अपने प्रश्न में स्क्रिप्ट को अधिक जोड़ते हैं, तो मैं सुझाव दे सकता हूं कि यह कहां से आ रहा है।

अपडेट करें

पूरी स्क्रिप्ट को देखते हुए, मैं सिर्फ लाइन को बदलूंगा:

result=$(echo "$used / $total * 100" |bc -l|cut -c -2)

साथ में:

result=$(( 100 * used / total ))

चूंकि usedऔर totalपूर्णांक हैं और bashपूर्णांक अंकगणित करता है, हालांकि ध्यान दें कि गुणा का स्थानांतरण शुरुआत में 100 हो। या यदि आप सही राउंडिंग सुनिश्चित करना चाहते हैं (कंप्यूटिंग में 'पूर्णांक विभाजन' हमेशा प्रभावी रूप से राउंड डाउन होता है):

result=$( printf '%.0f' $(echo "$used / $total * 100" | bc -l) )

यह सुनिश्चित करेगा कि इसमें कोई अनुगामी बिंदु नहीं हैं result। उपयोग करने का दृष्टिकोण cutबहुत अच्छा विचार नहीं है क्योंकि यह केवल 10-99 की सीमा में परिणाम के लिए मान्य है। यह result0-9 से (आपके मामले में) और 99 से ऊपर की संख्या के लिए भी विफल हो जाएगा ।

अपडेट २

से @ नीचे स्टीफ़न की टिप्पणी , आप जब थ्रेसहोल्ड की तुलना दौर नीचे करने के लिए बेहतर होते हैं। इस पर विचार करते हुए, प्रश्न में स्निपेट के साथ एक और छोटी सी त्रुटि है - warn_levelऔर के लिए उपयोग की जाने वाली तुलना के बीच असंगति को नोटिस करें critical_level। के लिए तुलना warn_levelसही है, लेकिन (कम) के बजाय (कम या बराबर) critical_levelका उपयोग करता है । विचार करें कि कब की तुलना में थोड़ा बड़ा है - इसे नीचे की ओर गोल किया जाएगा और महत्वपूर्ण चेतावनी को ट्रिगर नहीं किया जाएगा, भले ही यह (और अगर तुलना का उपयोग किया गया था)।-le-ltresultcritical_levelcritical_level-lt

शायद कोई समस्या नहीं है, लेकिन यहाँ सही कोड है:

if [ "$result" -lt "$warn_level" ]; then
  echo "Memory OK. $result% used."
  exit 0;
elif [ "$result" -lt "$critical_level" ]; then
  echo "Memory WARNING. $result% used."
  exit 1;
else
  echo "Memory CRITICAL. $result% used."
  exit 2;
fi

-geपरीक्षण भी बेमानी हैं, क्योंकि इन मामलों तक पहुंचने पर लगाए गए elif/ else, इसलिए हटा दिया गया है।


2
हालांकि, थ्रेसहोल्ड के खिलाफ जांच करने के लिए, आप नहीं पूर्णांक बनाना चाहते हैं अप । 49.6 अभी भी ठीक होना चाहिए अगर चेतावनी सीमा 50 है। तो result=$(( 100 * $used / $total ))बस ठीक होना चाहिए।
स्टीफन चेज़लस

0

तो मैं नहीं जानता कि कैसे awkबहुत अच्छी तरह से उपयोग करने के लिए । लेकिन मुझे पता है कि आपके द्वारा लिंक की गई स्क्रिप्ट में क्या चल रहा है, यह बहुत बकवास है और यह कि निम्नलिखित की तरह कुछ काम करना चाहिए। मुझे खेद है कि मैं इसे पूरी तरह से नहीं लिख सकता, लेकिन जब से आप पहले से ही कॉल कर रहे हैं awk- दो बार ऐसा लगता है - आपको कुछ इस तरह का उपयोग करना चाहिए।

_chkmem() { return $( 
    free -m | grep "buffers/cache"
        awk '{ 
        percent = ( $3 / ( $3 + $4 ) ) * 100     
        warn = '"${warnlevel?No warning level specified!}"' < percent ? WARNING : OK
        crit = '"${critical?No critical level specified!}"' < percent ? CRITICAL : $warn
        print "Mem $crit : $percent% used"
        if ( $crit != OK ) exit 1
    }')
}

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