Bash komut dosyası hatası: tamsayı ifadesi bekleniyor


13

Oldukça garip bir sorun yaşıyorum, birden çok sunucuda bir komut dosyası (Bash) çalıştırıyorum ve sunuculardan birinde çalışmayı durdurdu (diğer tüm sunucularda mükemmel çalışıyor).

İşte script sorunu parçasıdır: ((kendim yazmadım, bütün kredi "Zengin" gidin) http://www.notrainers.org/monitoring-memory-usage-on-linux-with-nagios- and-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

Tam hata mesajı:

./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

Daha fazla bilgiye ihtiyacınız varsa, bana bildirin, mümkün olduğunca hızlı bir şekilde tedarik etmeye çalışacağım.

Tüm girdileri takdir edin :)

Yanıtlar:


5

Sağladığınız bağlantıdan aşağıdaki satırı görüyorum.

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

@ Graeme'nin yorumuna göre yukarıdaki satırı aşağıya değiştirin.

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

Şimdi, yukarıdaki satırı ekledikten sonra, resulttamsayıya çıkışını aşağıdaki gibi değiştirmeliyiz .

result1=${result/.*}

Sanırım hatanın meydana geldiği makinelerden birinde, bu çıktı bir tamsayı değil. Sonuçların çıktısını tamsayıya dönüştürün, böylece bu gibi durumları halledebilirsiniz. Hesapladıktan sonra aşağıdaki satırı ekleyin result.

result1=${result/.*}

resultDeğişken adlarını döngülerin result1içindeki gibi değiştirmek yerine ifhata oluşmaz.

Şüpheliyim, cut -c -2hataya ilişkin öznitelikler çoğunlukla sadece ilk 2 karakteri kesiyor. Sonuçta sadece bir karakter varsa ne olur? Sonuç ise 1.23456, yukarıdaki kesimin , hatanın nedeni açıkça olduğu 1.değer olarak sonuçlanacağını varsayalım .resultinteger expected

Geri kalan sunucularda iyi çalışmasının nedeni, resultdeğişkenin sadece tek bir basamağa sahip olduğu bir durumla karşılaşmamasıdır . Sonuç tek haneli bir değişkense (yukarıdaki örnekte bahsettiğim gibi) kalan sunucularda da başarısız olma olasılığı yüksektir.


${result%%.*}burada ondalık noktayı kaldırmak için doğru genişleme olacaktır. Ancak cut -c -2, 100 veya daha fazla sayı ile ilgili sorunlara da neden olacağını unutmayın , bu yüzden tamamen düşürmek daha güvenlidir.
Graeme

@Graeme, bunu kaçırdım. Bu satırda değişiklikler yapmalıydım :)
Ramesh

6

Şeylere bakıldığında, resultdeğişkeniniz .bash'ın onu tanımamasını sağladıktan sonra değişkeninizin içinde bir tane var . Hatayı basitçe yaparak yeniden üretebilirsiniz:

[ 7. -gt 1 ]

Sorunuza daha fazla komut dosyası eklerseniz, | bunun nereden gelebileceğini önerebilirim.

Güncelleme

Tam betiğe baktığımda, sadece satırı değiştirirdim:

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

İle:

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

Yana usedve totaltamsayılar ve bashnota rağmen, aritmetik tamsayı yapar çarpma kaydırılması başına 100 olmak. Veya doğru yuvarlamayı sağlamak istiyorsanız (hesaplamadaki 'tamsayı bölümü' her zaman etkili bir şekilde aşağı yuvarlar):

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

Bu, içinde hiçbir nokta bulunmamasını sağlayacaktır result. Kullanım yaklaşımı cutçok iyi bir fikir değildir, çünkü sadece 10-99 aralığındaki sonuç için geçerlidir. result0-9 arası (sizin durumunuzda olduğu gibi) ve 99'un üzerindeki sayılar için başarısız olacaktır .

Güncelleme 2

Gönderen aşağıda Stephane'ın yorumun @ eşikleri karşılaştırırken, sen yuvarlak aşağı etmek daha iyidir. Bu göz önüne alındığında, soruda snippet ile ilgili başka bir küçük hata daha var - warn_levelve için kullanılan karşılaştırmalar arasındaki tutarsızlığa dikkat edin critical_level. İçin karşılaştırmalar warn_leveldoğru ancak critical_levelkullanımları -leyerine (daha az veya buna eşit) -lt(sadece daha az). Ne zaman resultbiraz daha büyük olduğunu düşünün critical_level- critical_levelkritik uyarıya yuvarlanacak ve tetiklenmeyecek olsa bile (bir -ltkarşılaştırma kullanılmışsa) tetiklenmeyecektir .

Belki çok fazla sorun değil, ama burada düzeltilmiş kod:

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

-geBu durumlar ulaşırken ima beri testler de gereksizdir elif/ elseyüzden kaldırıldı.


2
Ancak, eşiklere karşı kontrol etmek, Yuvarlamak istemiyoruz kadar . 49.6 hala olmalıdır Tamam uyarı eşiği Yani 50 ise result=$(( 100 * $used / $total ))sadece iyi olmalıdır.
Stéphane Chazelas

0

Bu yüzden nasıl awkçok iyi kullanacağımı bilmiyorum . Ancak, bağladığınız senaryoda olanların çok saçma olduğunu ve aşağıdakine benzer bir şeyin çalışması gerektiğini biliyorum. Üzgünüm bunu iyi yazamıyorum, ama zaten aradığınızdan awk- iki kez görünüyor - böyle bir şey kullanıyor olmalısınız.

_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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.