linuxbashshellmonitoringiostat

Comparing floating-point numbers in bash


In my custom bash script for server monitoring , which actually made to force my CentOS server take some actions and alert me if resources are overloaded more time than expected, I get the following error

line 17: [: 5.74: integer expression expected *

Now by definition all iostat results are float numbers and I already have used awk in my iostat command (WAIT) so how I can make my bash script to expect one instead of integer ?

** Value 5.74 represents current iostat result

#!/bin/bash

if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then
#       echo "Script is already running with PID `pidof -x $(basename $0) -o %PPID`"
        exit
fi

UPTIME=`cat /proc/uptime | awk '{print $1}' | cut -d'.' -f1`
WAIT=`iostat -c | head -4 |tail -1 | awk '{print $4}' |cut -d',' -f1`
LOAD=`cat /proc/loadavg |awk '{print $2}' | cut -d'.' -f1`

if [ "$UPTIME" -gt 600 ]
then
        if [ "$WAIT" -gt 50 ]
        then
                if [ "$LOAD" -gt 4 ]
                then
                        #action to take (reboot, restart service, save state sleep retry)
                        MAIL_TXT="System Status: iowait:"$WAIT" loadavg5:"$LOAD" uptime:"$UPTIME"!"
                        echo $MAIL_TXT | mail -s "Server Alert Status" "mymail@foe.foe"
                        /etc/init.d/httpd stop
#                       /etc/init.d/mysql stop
                        sleep 10
#                       /etc/init.d/mysql start
                        /etc/init.d/httpd start
                fi
        fi
fi

CentOS release 6.8 (Final) 2.6.32-642.13.1.el6.x86_64


Solution

  • Normally, you'd need to use something other than native shell math, as described in BashFAQ #22. However, since you're comparing to integers, this is easy: You can just truncate at the decimal point.

    [ "${UPTIME%%.*}" -gt 600 ] # truncates your UPTIME at the decimal point
    [ "${WAIT%%.*}" -gt 50 ]    # likewise