0

This question already has an answer here:

My code:

#!/bin/bash

x=${#}

for (( a=0; a<x; ++a)); do
   if [[ $1 -eq $1 ]] 2> /dev/null
   then
      variable[a]=${1}
      shift
   else
      echo "The argument $1 is NOT an integer. Aborting this"
      exit 1
   fi
done
TOTAL=0
for (( a=0; a<x; ++a)); do
      echo "TOTAL : ${TOTAL}"
      TOTAL=$((TOTAL+variable[a]))
done
echo "Everything accounted to $TOTAL"
exit 0

So basically it takes the arguments of the script and sums them up. If one of the arguments is not an integer, it should tell you and exit the script.

The way it is right now it doesn't tell me if one of the arguments isn't an integer, it just skips it. So giving it the arguments 123 123 123 asdt, I get the following:

vagrant@localhost vagrant]$./super.sh 123 123 123 asdt
TOTAL : 0
TOTAL : 123
TOTAL : 246
TOTAL : 369
Everything accounted to 369
[07:43----------------------------------------
vagrant@localhost vagrant]$

But if I change it to this:

for (( a=0; a<x; ++a)); do
   if [ $1 -eq $1 ] 2> /dev/null
   then

It works and I get this:

vagrant@localhost vagrant]$./super.sh 123 123 123 asdt
The argument asdt is NOT an integer. Aborting this
[07:44----------------------------------------
vagrant@localhost vagrant]$

Why does that happen?

marked as duplicate by Ipor Sircer, maulinglawns, Jeff Schaller, Romeo Ninov, meuh Aug 22 '18 at 18:31

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • It's a fair question I think - see for example How do I test if a variable is a number in Bash? in particular the CAVEATS. Bottom line is you are relying on behavior that is unspecified in POSIX. – steeldriver Aug 22 '18 at 12:40
  • indeed, the test case here can be boiled down to [[ asdt -eq asdt ]] && echo yes versus [ asdt -eq asdt ] && echo yes – Jeff Schaller Aug 22 '18 at 12:44
3

It's one of the things how [[ .. ]] is special in Bash. [[ a -eq b ]] forces a and b to be taken as arithmetic expressions, and within one, a string is taken as the name of a variable. Other expressions works too, so you can do this:

$ a=2
$ [[ a -eq 1+1 ]] && echo yes
yes

On the other hand, [ is an ordinary command, and obeys the same syntax as normal commands. It might even be implemented as an external binary. Here, [ will just see a, and complain that it's not really an integer.

$ [ a -eq 2 ] && echo yes
bash: [: a: integer expression expected
$ /usr/bin/[ a -eq 2 ] && echo yes
/usr/bin/[: invalid integer ‘a’

Just use something like

a=asdf
if [[ $a = *[^0-9]* ]]; then
    echo "'$a' isn't an integer"
fi

or

a=asdf
case "$a" in 
    *[^0-9]*) echo "'$a' isn't an integer";;
esac

Apparently, ksh does the arithmetic evaluation of a and 1+1 even in [ a -eq 1+1 ].

  • @Isaac, well well. Luckily for me, this was tagged Bash. – ilkkachu Aug 26 '18 at 9:57

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