Bash: Test if argument is an integer

Submitted by dag on Wed, 2011/03/09 - 08:34

I haven't blogged as much as I used to, here's hoping I find some time to keep this up :-)

Something I always have to look up in older code is how to test if an argument is numerical. This can be useful for a function that optionally accepts something like a return-code, but also accepts a long string (eg. an error message). Putting the return-code at the end of a long string is far from developer-friendly and the error-message doesn't have to be single string.

To test if an argument is an integer, it is sufficient to test if it is greater or equal than zero (which an integer should be), if that test fails you know it's not an integer. You will have to suppress the bash error though.

if (( $1 >= 0 )) 2>/dev/null; then
  echo "Argument $1 is integer"
fi

And this is one of the uses for such a test:

### Set RETURNCODE either by return-code of previous command, numerical argument or running a command
function retcode {
  RETCODE=$?
  set +x
  if [[ "$1" ]]; then
    if (( $1 >= 0 )) 2>/dev/null; then
      RETCODE=$1
    else
      eval $@
      retcode
    fi
  fi
  [[ "$DEBUG" ]] && set -x || :
  return $RETCODE
}

This can be used like:

mount -a
retcode

retcode 5

retcode mount -a

mount -a
if ! retcode; then
  error "Error: command \"mount -a\" failed with RC $RETCODE"
fi

Depending on the situation and handling of RETCODE in your framework.

Pedant alert...

$ cat /tmp/bash-test ; /tmp/bash-test foo
#!/bin/bash

if (( $1 >= 0 )) 2>/dev/null; then
echo "Argument '$1' is integer"
fi

Argument 'foo' is integer

I've used bash's regex support to test for an integer when I was handling options, e.g.:

if [[ $1 =~ ^[0-9]+$ ]] && [[ $1 -gt 0 ]]; then
echo "Argument '$1' is integer"
fi

Just numerically compare it

Just numerically compare it to itself.


is_int() {
  if test ${1} -eq ${1} 2>/dev/null; then
    return 0
  fi
  return 1
}

is_int ${var} && echo "that's an int"

Nice one ! :-)

Nice one ! :-)

This test for integer is not reliable


#!/bin/bash

if (( $1 >= 0 )) 2>/dev/null; then
echo "Argument $1 is integer"
else
echo "Argument $1 is NOT integer"
fi

...

./testinteger xxx
Argument xxx is integer

Sorry, I didn't see Todd's comment

Carl-Christian tried a different test, but it is also not complete, because it counts the null string and any number of blanks as int.