Bash脚本错误:预期为整数表达式


13

我遇到了一个很奇怪的问题,我在多个服务器上运行脚本(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

如果您需要更多信息,请告诉我,我将尝试尽快提供。

感谢所有输入:)

Answers:


5

从您提供的链接中,我看到以下行。

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

根据@Graeme的评论,将上面的行更改为下面的行。

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

现在,在添加以上行之后,我们必须将的输出更改result为整数,如下所示。

result1=${result/.*}

我猜在其中发生错误的机器之一中,此输出不是整数。只需将结果的输出转换为整数,以便您可以处理这种情况。计算后,添加以下行result

result1=${result/.*}

而不是resultresult1if循环中那样更改变量名,并且不会发生错误。

我怀疑,cut -c -2错误的属性主要是因为它仅剪切了前2个字符。如果结果只有一个字符怎么办?假设如果结果为1.23456,则上述切割将1.作为result显然是导致integer expected错误的原因的值。

它在其余服务器上运行良好的原因是,它没有遇到result变量只有一位数字的情况。如果结果是一个数字变量(在上面的示例中我提到过),那么在其余服务器中也很有可能失败。


${result%%.*}是删除此处小数点的正确扩展。但是请注意,这cut -c -2还会导致数量大于或等于100的问题,因此将其完全丢弃会更安全。
Graeme 2014年

@Graeme,我错过了。我应该在该行中进行更改:)
Ramesh 2014年

6

从外观上看,result变量.使bash不能将其识别为数字之后,变量中就有一个。您只需执行以下操作即可重现错误:

[ 7. -gt 1 ]

如果您向问题中添加更多脚本,|我可以建议它可能来自何处。

更新资料

查看完整的脚本,我只需要替换以下行:

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

带有:

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

由于usedtotal是整数,并且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
然而,要检查的阈值,你不想圆。49.6应该还是OK,如果警告阈值是50.所以result=$(( 100 * $used / $total ))应该就好了。
斯特凡Chazelas

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.