Read string and convert to INT (BASH)

11,457

Solution 1

The problem occurs when $output is the empty string; whether or not you quote the expansion (and you should), you'll get the integer expression required error. You need to handle the empty string explictly, with a default value of zero (or whatever default makes sense).

wget=$(wget http://10.228.28.8/ -O /tmp/wget.txt 2>/dev/null)
output=$(awk 'NR==6' < /tmp/get.txt)
output=${output:-0}

if [ "$output" -ge 11 ];then
  echo "CRITICAL: $output"
  exit 2
elif [ "$output" -ge 6 ];then
  echo "WARNING: $output"
  exit 1
else
  echo "OK: $output"
  exit 0
fi

(If you reach the elif, you already know the value of $output is less than 11; there's no need to check again.)


The problem also occurs, and is consistent with the error message, if output ends with a carriage return. You can remove that with

output=${output%$'\r'}

Solution 2

There are a couple of suggestions from my side regarding your code.

You could explicitly tell bash the output is an integer

declare -i output # See [1]

Change

output=$(cat /tmp/wget.txt | awk 'NR==6') # See [2]

may be better written as

output=$(awk 'NR==6' /tmp/wget.txt )

Change

if [ $output -ge 11 ]

to

if [ "0$output" -ge 11 ] # See [4]

or

if (( output >= 11 )) # Better See [3]

References

  1. Check bash [ declare ].
  2. Useless use of cat. Check [ this ]
  3. Quoting [ this ] answer :

    ((...)) enable you to omit the dollar signs on integer and array variables and include spaces around operators for readability. Also empty variable automatically defaults to 0 in such a statement.

  4. The zero in the beginning of "0$output" help you deal with empty $output

Interesting
Useless use of cat is a phrase that has been resounding in SO for long. Check [ this ]
[ @chepner ] has dealt with the empty output fiasco using [ bash parameter expansion ] in his [ answer ], worth having a look at.

Share:
11,457
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I have a simple script in Bash to read a number in a file and then compare it with a different threshold. The output is this:

    : integer expression expected
    : integer expression expected
    OK: 3
    

    My code is this:

    #!/bin/bash
    
    wget=$(wget http://10.228.28.8/ -O /tmp/wget.txt 2>/dev/null)
    output=$(cat /tmp/wget.txt | awk 'NR==6')
    #output=7
    echo $output
    
    if [ $output -ge 11 ];then
        echo "CRITICAL: $output"
        exit 2
    elif [ $output -ge 6 ] && [ $output -lt 11 ];then
        echo "WARNING: $output"
        exit 1
    else
        echo "OK: $output"
        exit 0
    fi
    
    rm /tmp/wget.txt
    

    I know what is the problem, I know that I'm reading a string and I try to compare a int. But I don't know how can I do to read this file and convert the number to read in a int var..

    Any ideas?

  • chepner
    chepner almost 8 years
    Quotes should be used, but they won't help in the current situation, where $output is empty. (( output >= 11)) will work, since an empty variable automatically defaults to 0 in such a statement.
  • sjsam
    sjsam almost 8 years
    @chepner: Thankyou, rectified.
  • ghoti
    ghoti almost 8 years
    If $output is empty, you can replace it with zero using ${output:-0}.
  • Fazlin
    Fazlin almost 8 years
    But if you watch his output it prints OK: 3 which is the echo "OK: $output" in the else condition. So $output is not empty
  • ghoti
    ghoti almost 8 years
    You could eliminate the extra variable assignment by putting things into awk. output=$(awk 'NR==6{printf("%d",$1)}') /tmp/wget.txt
  • chepner
    chepner almost 8 years
    Ah, true. I bet the output of OK: $output= would be enlightening, though. There is probably a carriage return at the end of the value.
  • sjsam
    sjsam almost 8 years
    @ghoti : The other answer already mention that approach. Is there an obvious disadvantage with my method?
  • Мона_Сах
    Мона_Сах almost 8 years
    @sjsam : Setting output to zero if it is not set seem the most sensibel approach here.
  • ghoti
    ghoti almost 8 years
    @sjsam, your approach is fine if there's 100% confidence that $output will always be an integer (and therefore interpreted correctly by [ $output -ge ... etc.) In my own shell programming, I always strive to add error handling so that if inputs are not structured as expected, we can detect and perhaps control the behaviour rather than just failing. Your reference #3 is great, but perhaps it would be even better to throw an error and warning if $output is empty. Since the script in the Q looks like a Nagios script, then perhaps a null/empty value should return an UNKNOWN response.
  • sjsam
    sjsam almost 8 years
    @ghoti : Appreciate the time. Hope my link to \@chepner's answer will help me not posting the redundant content in this one and I hope the op will pay attention to that answer and your comment above. :)