0

I am trying to write a script which connects to a database then run a query that returns count of rows in a table. sometimes database or table have problems and instead of an integer they return an error. for example:
A database connection does not exist
i want to determine if output is the integer i want or its an error. i searched through various posts but none of them worked in my script. what should i do?

DB2PATH=/bin/db2
$DB2PATH connect to $1 >> /dev/null
count=$($DB2PATH -x " select count(*) from TEST122 ")


if ! [[ "$count" =~ ^[0-9]+$ ]]
then
    echo "string"
else
    echo $count
fi

i changed the if condition in many different ways. i used -eq and -ne. it keep returning string. and the value of count is 11.

update:
printf '%s' "$count" | hexdump -c output:

0000000                                       1   1
000000b
  • 1
    If count is actually 11, the if works fine for me. Maybe the command output has spaces in it, or quotes, or some other weird characters. – muru Oct 31 '18 at 8:19
  • 3
    @BlackCrystal: Can you do printf '%s' "$count" | hexdump -c and paste above? – Inian Oct 31 '18 at 8:20
  • @Inian what does that command do? i edited my post – BlackCrystal Oct 31 '18 at 8:26
  • 2
    @BlackCrystal: As muru has indicated in his comment, the variable has some extra spaces present, that's why you see it is matching the string type – Inian Oct 31 '18 at 8:27
2

Looks like the variable count has some extra undesirable spaces which is causing your condition to fail it to be an integer type.

You need to strip out the extra spaces in your variable to fix it. Use an external tool like xargs to remove the spaces. The useful thing with xargs is it swallows up both leading and trailing spaces in the variable.

if ! [[ $( xargs <<< "$count" ) =~ ^[0-9]+$ ]]
then
    echo "string"
else
    echo $count
fi

If not for an external tool like xargs use the parameter expansion provided by the shell itself

if ! [[ "${count// /}" =~ ^[0-9]+$ ]]
then
    echo "string"
else
    echo $count
fi

The syntax ${count// /} will replace all the spaces with an empty string and the resultant string is used in the comparison with the regular expression defined.

  • 1
    You could also use the arithmetic context: (( count = count )) will succeed and convert count to a number if it didn't have invalid characters (leading, trailing spaces are fine). It will fail with invalid characters, so you could do if (( count = count )); then echo "$count"; else echo string; fi – muru Oct 31 '18 at 8:38
  • 2
    @muru, that's both wrong and dangerous, (( count = count )) returns true if $count contains an artihmetic expression that resolves to a non-0 number. So it returns false for 0 even though that's a valid decimal number, and true for RANDOM (most likely), 1 + a[$(reboot)0] (which also reboots), PATH=123... – Stéphane Chazelas Oct 31 '18 at 9:16
  • 1
    Note that your first one would think that '1'\2"3" or -n 123 (with some echo implementations) is a valid number. The second one would think that 1 2 34 is a valid number. – Stéphane Chazelas Oct 31 '18 at 9:23
  • @StéphaneChazelas woah. Thanks for the correction! – muru Oct 31 '18 at 9:30
  • 2
3

To ignore and trim leading and trailing whitespace around the number:

if [[ $count =~ ^[[:space:]]*([[:digit:]]+)[[:space:]]*$ ]]; then
  echo number
  count=${BASH_REMATCH[1]}
else
  echo other
fi

Or with standard sh syntax:

trimmed=${count#"${count%%[![:space:]]*}"}
trimmed=${trimmed%"${count##*[![:space:]]}"}
case $trimmed in
  ("" | *[![:digit:]]*) echo other;;
  (*) echo number; count=$trimmed;;
esac
0

Putting negation inside expresion gives me correct results:

if [[ ! "$count" =~ ^[0-9]+$ ]]
then
    echo "string"
else
    echo $count
fi

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.