1

I have a bash script in which I am attempting to compare a variable containing a whole number

VAR1=1

The real number to compare to, can be a decimal

VAR2=1.5

When I try:

if [[ $VAR1 -ge $VAR2]];

I am presented with a syntax error: invalid arithmetic operator

The problem is, when I try the >= string comparison, the result is always false irregardles of whether it logically is or not.

My question is, how can I fix this and do the arithmatic comparison?

Code Block

if [ $(bc -l <<<"$CPUUSAGE >= $MAXCPU") || $(bc -l <<<"$FREEMEM <= $MAXMEM") || $NUMHTTPD -ge $MAXHTTPD || $NUMMYSQL -ge $MAXMYSQL || $NUMPROCS -ge $MAXPROCESSES ]];
then    
    SendMessage;
    sync ; echo 3 > /proc/sys/vm/drop_caches;
    echo "Message Sent";
fi;
Community
  • 1
  • 1
Kevin
  • 2,684
  • 6
  • 35
  • 64
  • 1
    possible duplicate of [How to compare two floating point numbers in a bash script?](http://stackoverflow.com/questions/8654051/how-to-compare-two-floating-point-numbers-in-a-bash-script) – Arkadiusz Drabczyk Mar 26 '15 at 12:53

3 Answers3

2

bash does not support floating point operations. You could use bc for that:

if  [ $(bc --mathlib <<< "$var1 >= $var2") = "1" ] ; then
    echo "$var2 is greater than or equal to $var2"
fi

Note that unless you pass the --mathlib option, even bc would not support floating point operations.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
2

Bash doesn't support floating point numbers.

Try bc:

(( $(bc -l <<<"$v1 >= $v2") )) && echo "v1 is greater than or equal to v2"

I have used some bashisms here, notably the (( arithmetic context )) and <<< as an alternative to echoing the string to bc. The output of bc will be 1 or 0, depending on whether the statement is true or false. The message will only be echoed if the result is true.

The -l switch is shorthand for --mathlib, which as hek2mgl rightly asserts, is needed when working with floating point numbers.

If you want a fully-fledged if statement, you can do that as well:

if (( $(bc -l <<<"$v1 >= $v2") )); then
    echo "v1 is greater than or equal to v2"
else
    echo "v1 is less than v2"
fi

For the example in your question, you could use this:

if (( $(bc -l <<<"$CPUUSAGE >= $MAXCPU || $FREEMEM <= $MAXMEM") )) || [[ $NUMHTTPD -ge $MAXHTTPD || $NUMMYSQL -ge $MAXMYSQL || $NUMPROCS -ge $MAXPROCESSES ]]; then echo; fi

I've combined the two conditions in bc to save you calling the tool twice. I've also wrapped that part in an arithmetic context and used an extended test [[ for the rest.

Community
  • 1
  • 1
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • 2
    The arithmetic context is great! (My first first version wouldn't even work ( while it had already two ups :) ) – hek2mgl Mar 26 '15 at 13:00
  • 1
    @hek2mgl thanks, the reason for my delay was that I was trying things similar to your post but couldn't get them to work :) – Tom Fenech Mar 26 '15 at 13:03
  • now getting [: missing `]' and command not found errors, sorry, I am a bash noob – Kevin Mar 26 '15 at 13:11
0

AWK can do the trick too:

#!/bin/sh

VAR1=1
VAR2=1.5

if awk "BEGIN {exit $VAR1 >= $VAR2 ? 0 : 1}"
then 
   echo "$VAR1 is greater than or equal to $VAR2" 
else
   echo "$VAR2 is greater than or equal to $VAR1"
fi
mlegge
  • 6,763
  • 3
  • 40
  • 67