Kesalahan skrip Bash: ekspresi integer diharapkan


13

Saya mengalami masalah yang agak aneh, saya menjalankan skrip (Bash) di beberapa server dan berhenti bekerja di salah satu server (berfungsi dengan sangat baik di semua server lain).

Inilah bagian masalah dari skrip: (Saya tidak menulisnya sendiri, semua kredit menjadi "Kaya") ( http://www.notrainers.org/monitoring-memory-usage-on-linux-with-nagios- dan-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

Pesan kesalahan lengkap:

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

Jika Anda memerlukan info lebih lanjut, beri tahu saya dan saya akan mencoba menyediakannya secepat mungkin.

Hargai semua input :)

Jawaban:


5

Dari tautan yang Anda berikan, saya melihat garis di bawah ini.

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

Sesuai komentar @ Graeme, ubah baris di atas ke bawah.

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

Sekarang, setelah menambahkan baris di atas, kita harus mengubah output resultke integer seperti di bawah ini.

result1=${result/.*}

Saya kira di salah satu mesin di mana kesalahan terjadi, output ini bukan bilangan bulat. Konversikan output dari hasil ke integer sehingga Anda dapat menangani kasus seperti itu. Tambahkan baris di bawah ini setelah Anda menghitung result.

result1=${result/.*}

Dan alih-alih resultmengubah nama variabel seperti result1di dalam ifloop, dan kesalahan tidak akan terjadi.

Saya menduga, cut -c -2atribut kesalahan sebagian besar karena hanya memotong 2 karakter pertama saja. Bagaimana jika hasilnya hanya memiliki satu karakter? Misalkan jika hasilnya adalah 1.23456, potongan di atas akan menghasilkan 1.nilai resultyang jelas merupakan penyebab integer expectedkesalahan.

Alasannya berfungsi dengan baik di server yang tersisa adalah karena belum menemukan kasus di mana resultvariabel hanya memiliki satu digit. Sangat mungkin untuk gagal di server yang tersisa juga jika hasilnya adalah variabel satu digit (seperti yang saya sebutkan dalam contoh di atas).


${result%%.*}akan menjadi ekspansi yang benar untuk menghilangkan titik desimal di sini. Tetapi perhatikan bahwa hal cut -c -2itu juga akan menyebabkan masalah dengan angka 100 atau lebih, sehingga lebih aman untuk menjatuhkannya sepenuhnya.
Graeme

@ Greme, aku merindukan itu. Saya seharusnya membuat perubahan di baris itu :)
Ramesh

6

Dari tampilan hal-hal, resultvariabel Anda memiliki .di dalamnya setelah angka membuat bash tidak mengenalinya. Anda dapat mereproduksi kesalahan hanya dengan melakukan:

[ 7. -gt 1 ]

Jika Anda menambahkan lebih banyak skrip ke pertanyaan Anda, | Saya dapat menyarankan dari mana asalnya.

Memperbarui

Melihat skrip lengkap, saya hanya akan mengganti baris:

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

Dengan:

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

Karena useddan totaladalah bilangan bulat dan bashmelakukan bilangan bulat aritmatika, meskipun perhatikan bahwa pergeseran perkalian menjadi 100 ke awal. Atau jika Anda ingin memastikan pembulatan yang benar ('divisi integer' dalam komputasi selalu dibulatkan secara efektif):

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

Ini akan memastikan bahwa tidak ada titik tertinggal di result. Pendekatan menggunakan cutbukan ide yang sangat bagus karena hanya valid untuk hasil di kisaran 10-99. Ini akan gagal untuk resultdari 0-9 (seperti dalam kasus Anda) dan juga angka di atas 99.

Perbarui 2

Dari komentar @ Stephane di bawah ini , Anda lebih baik membulatkannya saat membandingkan dengan ambang batas. Mempertimbangkan hal ini, ada kesalahan kecil lainnya pada cuplikan dalam pertanyaan - perhatikan ketidakkonsistenan antara perbandingan yang digunakan untuk warn_leveldan critical_level. Perbandingan untuk warn_levelbenar, tetapi critical_levelmenggunakan -le(lebih kecil atau sama) bukan -lt(hanya lebih sedikit). Pertimbangkan kapan resultsedikit lebih besar dari critical_level- itu akan dibulatkan ke bawah critical_leveldan tidak memicu peringatan kritis meskipun seharusnya (dan akan jika -ltperbandingan digunakan).

Mungkin tidak banyak masalah, tapi ini kode yang diperbaiki

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

The -getes juga berlebihan karena kasus-kasus ini tersirat pada mencapai elif/ else, sehingga telah dihapus.


2
Namun, untuk memeriksa terhadap ambang, Anda tidak ingin untuk putaran atas . 49.6 harus tetap OK jika ambang peringatan adalah 50. Jadi result=$(( 100 * $used / $total ))harus baik-baik saja.
Stéphane Chazelas

0

Jadi saya tidak tahu bagaimana menggunakannya dengan awksangat baik. Tetapi saya tahu bahwa apa yang terjadi dalam skrip yang Anda tautkan adalah omong kosong dan sesuatu seperti yang berikut ini akan berfungsi. Maaf saya tidak bisa menulis ini dengan baik, tetapi karena Anda sudah menelepon awk- sepertinya dua kali - Anda harus menggunakan sesuatu seperti ini.

_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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.