POSIX Shell Script – How to Check if Variable is Integer

posixscriptingshell-script

My POSIX is_integer () function looks like this for a long time:

#!/bin/sh
is_integer ()
{
    [ "$1" -eq "$1" ] 2> /dev/null
}

However, today, I found it broken. If there are some spaces around the number, it surprisingly also evaluates to true, and I have no idea how to fix that.


Example of correct (expected) behavior:

is_integer 123 evaluates to true.

Example of incorrect (unexpected) behavior:

is_integer ' 123' also evaluates to true, however it obviously contains a leading space, thus the function is expected to evaluate to false in such cases.


POSIX-compliant suggestions only, please. Thank you.

Best Answer

#!/bin/sh
is_integer ()
{
    case "${1#[+-]}" in
        (*[!0123456789]*) return 1 ;;
        ('')              return 1 ;;
        (*)               return 0 ;;
    esac
}

Uses only POSIX builtins. It is not clear from the spec if +1 is supposed to be an integer, if not then remove the + from the case line.

It works as follows. the ${1#[+-]} removes the optional leading sign. If you are left with something containing a non digit then it is not an integer, likewise if you are left with nothing. If it is not not an integer then it is an integer.

Edit: change ^ to ! to negate the character class - thanks @LinuxSecurityFreak