简体   繁体   中英

Read string and convert to INT (BASH)

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?

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'}

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.

A simplified script:

#!/bin/bash

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

output="$(( 10#${output//[^0-9]} + 0 ))"

(( output >= 11 )) && { echo "CRITICAL: $output"; exit 2; }
(( output >=  6 )) && { echo  "WARNING: $output"; exit 1; }
echo "OK: $output"

The key line to cleanup any input is:

output="$(( 10#${output//[^0-9]} + 0 ))"

${output//[^0-9]} Will leave only digits from 0 to 9 (will remove all non-numeric chars).

10#${output//[^0-9]} Will convert output to a base 10 number.

That will correctly convert numbers like 0019

"$(( 10#${output//[^0-9]} + 0 ))" Will produce a zero for a missing value.

Then the resulting number stored in output will be compared to limits and the corresponding output will be printed.

In BASH, It is a good idea to use double brackets for strings:

if [[ testing strings ]]; then
    <whatever>
else
    <whatever>
fi

Or double parenthesis for integers:

if (( testing ints )); then
    <whatever>
else
    <whatever>
fi

For example try this:

var1="foo bar"
if [ $var1 == 'foo bar' ]; then
    echo "ok"
fi

Result:

$ bash: [: too many arguments

Now, this:

var2="foo bar"
if [[ $a == "foo bar" ]]; then
    echo "ok"
fi

Result:

ok

For that, your code in BASH:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM