Error: integer expression expected

5,675

Solution 1

bash (contrary to ksh93 or zsh1) can't do floating point arithmetics. awk can though, so you can do the whole thing in awk.

Also, you don't need to use top (and wait 1 second) to get the load. The canonical way to get the load is from uptime.

uptime | awk '{load=+$(NF-2)}
  load > 2 {print "CRITICAL: " load; exit 2}
  load > 1 {print "WARNING: " load; exit 1}
  {print "OK: " load; exit 0}
  END {if (!NR) {print "UNKNOWN"; exit 3}'
exit

1 In zsh though, you need to use the (( loadavg > 2 )) instead of [ "$loadavg" -gt 2 ] syntax for comparing non-integers

Solution 2

top -b -n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $2}' returns nada, hence your errors.

Solution 3

Your loadavg is null, causes syntax errors by [:

$ top -b n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $2}'
<blank line here>

You must change it to:

$ top -b n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $1}'
 0.24

However, you should use newer test in your script, it can handle this problem:

$ [[ "" -gt 1 ]] || echo "OK"
OK

With older [:

$ [ "" -gt 1 ] || echo "OK"
bash: [: : integer expression expected
OK

Updated

bash can not handle floating point numbers, so your comparison (even with new test [[..]]) will show errors.

You can use another tools to do this task, like bc, awk...

Example:

$ [[ $(echo "3 > 1" | bc -l) == 1 ]] && echo OK
OK
$[[ $(echo "3 < 1" | bc -l) == 1 ]] || echo Not OK
Not OK
Share:
5,675

Related videos on Youtube

Mandar Shinde
Author by

Mandar Shinde

Updated on September 18, 2022

Comments

  • Mandar Shinde
    Mandar Shinde over 1 year

    I have written a script to determine the Load average on the server as follows:

    #!/bin/bash
    
    loadavg=`top -b -n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $2}'`
    
    if [ "${loadavg}" -le  1 ]
    then
    echo "OK - Load Average = ${loadavg} | Load_Average=${loadavg}"
    exit 0;
    elif [ "${loadavg}" -gt 1 ] && [ "${loadavg}" -le 2 ]
    then
    echo "WARNING - Load Average = ${loadavg} | Load_Average=${loadavg}"
    exit 1;
    elif [ "${loadavg}" -gt 2 ]
    then
    echo "CRITICAL - Load Average = ${loadavg} | Load_Average=${loadavg}"
    exit 2;
    else
    echo "UNKNOWN - Load Average = NaN | Load_Average=NaN"
    fi
    

    When the script is executed, it displays following error:

    ./loadavg.sh
    ./loadavg.sh: line 5: [:  0.06: integer expression expected
    ./loadavg.sh: line 9: [:  0.06: integer expression expected
    ./loadavg.sh: line 13: [:  0.06: integer expression expected
    UNKNOWN - Load Average = NaN | Load_Average=NaN
    
    • jasonwryan
      jasonwryan almost 10 years
      top -b n1 | awk -F, '/load/ {print $4}' is a lot cleaner...
    • Felix Frank
      Felix Frank almost 10 years
      How about loadavg=$( cut -d' ' -f1 </proc/loadavg ) - and no, still not an integer expression. It's a fixpoint. If you want to use -le and friends, consider cut -d' ' -f1 </proc/loadavg | cut -d. -f1, i.e. just drop everything after the integer part.
    • Stéphane Chazelas
      Stéphane Chazelas almost 10 years
      Nagios alread has a check_load. Why are you making your own?
    • Stéphane Chazelas
      Stéphane Chazelas almost 10 years
      Do the whole thing in awk. awk can do floating points, bash or [ cannot.
    • Stéphane Chazelas
      Stéphane Chazelas almost 10 years
      You can get the load from uptime, not need to run one iteration of top for that.
    • Mandar Shinde
      Mandar Shinde almost 10 years
      @StéphaneChazelas: Well spotted! I am doing this just for fun.
  • Mandar Shinde
    Mandar Shinde almost 10 years
    top -b -n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $2}' is printing 0.37 while top -b n1 | grep -i load | awk -F, '{print$4}'| awk -F: '{print $1}' prints load average. While the top -b -n1 | grep -i load output is top - 15:02:31 up 2 days, 23:15, 1 user, load average: 0.37, 0.42, 0.38.
  • Mandar Shinde
    Mandar Shinde almost 10 years
    top -b -n1 | grep -i load is displaying top - 15:02:31 up 2 days, 23:15, 1 user, load average: 0.37, 0.42, 0.38.
  • cuonglm
    cuonglm almost 10 years
    @MandarShinde: Yes, because you are parsing the output of top, it can produce different output. I tested in my Fedora machine. The main thing I want to show is you should using new test [[..]] instead of [..].
  • Mandar Shinde
    Mandar Shinde almost 10 years
    When I replaced every [ with [[ and every ] with ]], it displayed the error: ./loadavg.sh: line 5: [[: 0.00: syntax error: invalid arithmetic operator (error token is ".00"). Tested on Red Hat Enterprise Linux Server release 6.5.
  • cuonglm
    cuonglm almost 10 years
    @MandarShinde: bash can not understand float number, bash treat it as string, causing this error.
  • Mandar Shinde
    Mandar Shinde almost 10 years
    How should deal with this issue?
  • schaiba
    schaiba almost 10 years
    As said above, if you want to use floats with bash, use bc for example.
  • Felix Frank
    Felix Frank almost 10 years
    On Linux, looking up /proc/loadavg will be more economic than shelling out to uptime, albeit less portable.
  • Stéphane Chazelas
    Stéphane Chazelas almost 10 years
    @MandarShinde, that depends on the top implementation. That also depends on whether there are processes with load in their name or username. Though you're right that it's not the problem the OP is facing.