0

I am new to bash scripting. My code is :

MK=M
SM=1.4

if [[ $MK == "M" ]]
 then
        if [ $SM -gt 1.3 ]
            then
            echo "Greater than 1.3M"
            else
            echo "Less than 1.3M"
            fi
 else
 echo "Not yet M...."
fi

Reply:

/tmp/tmp.sh: line 6: [: 1.4: integer expression expected
Less than 1.3M

What am i doing wrong ?

Fahad Ahammed
  • 371
  • 1
  • 11
  • 23

2 Answers2

3

Here's what man bash says:

arg1 OP arg2 ... Arg1 and arg2 may be positive or negative integers.

You seem to be trying to compare floating point numbers.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
3

It's ultimately because bash is not terribly patient when it comes to floating point numbers. In very simple terms here, I would suggest you do one of two things:

  1. It looks like you are trying to determine if something is larger than 1.3 Mb or not, is this correct? If this is the case, then leave everything the way you have it, and just use Kb for $sm and the compare

    like this:

    #/bin/bash
    
    mk="p"  
    km="p"  
    sm="1400"  
    ms="1300"  
    
    if [[ $mk == $km ]]  
    then  
    if [ $sm > $ms ]  
    then  
    echo "Greater than 1.3M"  
    else  
    echo "Less than 1.3M"  
    fi  
    else  
    echo "Not yet M...."  
    fi
    

    or

  2. Use bc for the calculation of the floating point numbers...

    # /bin/bash
    
    mk="p"
    km="p"
    sm="1.4"
    ms="1.3"
    
    if [ $(echo "$mk == $km" | bc) ]
    then   
    if [ $(echo "$sm > $ms" | bc) ]
    then
    echo "Greater than 1.3M"
    else
    echo "Less than 1.3M"
    fi
    else
    echo "Not yet M...."
    fi
    

One more thing to note here, is that, as you can see from my code, I have primed new variables with the data, rather than using raw letters and numbers in boolean and compare operations, which can have some genuinely unexpected results. Also, while they may work in some conditions, temporarily, bash prefers all variable names to be in lower-case. Let me know if you have any questions.. However, I have tested both code chunks, and they both work fine.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Matty
  • 111
  • 8
  • Oh... Right ... I can do that. Thanks. But Bash is not float friendly ? :( – Fahad Ahammed Apr 17 '16 at 14:15
  • Bash can absolutely handle floating points. You just need more code, in order to manipulate, compare and do arithmetic. If you need to use the floats, then as soon as I get into the office - which will be in an hour or so - I'll rewrite the code, using bc, which adds a couple of extra lines - and a few additional steps and processes to get your compares done. Let me know. – Matty Apr 17 '16 at 14:21
  • I would love to learn that, though using kilobytes fulfilled the need. Please if you have free time then do give me the lines about floating numbers in bash... :) – Fahad Ahammed Apr 17 '16 at 14:32
  • sometime in the next couple of hours I'll get it done for you.. Also, I forgot to mention (and I am sure you have already figured it out) that I didn't actually bother calculating Kb from 1.3Mb and 1.4Mb, I just averaged to 1300 and 1400 Kb respectively, if you really want to be accurate with your compares, you might want to do the maths :) – Matty Apr 17 '16 at 14:45
  • Thanks for sharing. It worked. – Fahad Ahammed Apr 18 '16 at 01:34
  • 1
    Bash _itself_ does _not_ handle floats; by contrast, _external utilities_ you can _call from_ Bash _may_ (e.g. `bc`). `>` in the context of `[ ... ]` and `[[ ... ]]` performs _lexical_ comparison, not numerical. Bash does _not_ care about the case of variables, but it's preferable to stay away from all-uppercase variables to avoid clashes with environment variables and Bash's built-in variables. – mklement0 Apr 18 '16 at 01:52
  • The syntax `if [ $(echo "$mk == $km" | bc) ]` didn't work for me. Instead, I had to add `-eq 1` for it to work: `if [ $(echo "$mk == $km" | bc) -eq 1 ]` – Mehdi Charife Mar 08 '23 at 02:59
  • For example, the code `if [ $(echo "5 < 2" | bc) ]; then echo "true" else echo "false" fi ` outputs true instead of false. – Mehdi Charife Mar 08 '23 at 03:01