我遇到了一个相当奇怪的问题,我正在多台服务器上运行脚本(Bash),但它在其中一台服务器上停止工作(在所有其他服务器上工作得很好)。
这是脚本的问题部分:(我自己没有写,所有学分都归“Rich”)(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
完整的错误消息:
./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
如果您需要更多信息,请告诉我,我会尽力尽快提供。
感谢所有的投入:)
答案1
从表面上看,你的result
变量.
在数字后面有一个 ,使得 bash 无法识别它。您只需执行以下操作即可重现该错误:
[ 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 范围内的结果有效。对于result
0-9(如您的情况)以及高于 99 的数字,它将失败。
更新2
从@Stephane 的评论如下,与阈值比较时最好向下舍入。考虑到这一点,问题中的代码片段还有另一个小错误 - 请注意用于 和warn_level
的比较之间的不一致critical_level
。的比较warn_level
是正确的,但critical_level
使用-le
(小于或等于)而不是-lt
(只是小于)。考虑何时result
略大于critical_level
- 它将向下舍入critical_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
从您提供的链接中,我看到以下行。
result=$(echo "$used / $total * 100" |bc -l|cut -c -2)
根据@Graeme 的评论,将上面的行更改为下面的行。
result=$(echo "$used / $total * 100" |bc -l)
现在,添加上述行后,我们必须将 的输出更改result
为整数,如下所示。
result1=${result/.*}
我猜想在发生错误的一台机器中,这个输出不是整数。只需将结果的输出转换为整数即可处理此类情况。计算 后添加以下行result
。
result1=${result/.*}
而不是在循环内result
更改变量名称,并且不会发生错误。result1
if
我怀疑,cut -c -2
错误的原因主要是因为它只剪切了前两个字符。如果结果只有一个字符怎么办?假设如果结果是1.23456
,则上述切割将导致1.
该值result
显然是导致错误的原因integer expected
。
result
它在其余服务器中工作正常的原因是它没有遇到变量只有一位数字的情况。如果结果是一位数字变量(就像我在上面的示例中提到的那样),那么在其余服务器中也很可能会失败。
答案3
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