Bash: Check that string is IP

Assuming that we have a Bash script that accepts a parameter that is expected to be an IP Address, this article lists a couple of (practically useless) ways of verifying that input without using regular expressions, which is the sane thing to do. It is therefore an exercise in futility, but it helps with my chronic allergy to regular expressions.

Breakdown of the conditions

First, check that exactly three dots exist in the string:

if [ `echo $IsIP | grep -o '\.' | wc -l` -ne 3 ]; then
    echo "Parameter '$1' does not look like an IP Address.";
    exit 1;
fi

Then, check that exactly four parts exist if the string is broken down by dots:

if [ `echo $IsIP | tr '.' ' ' | wc -w` -ne 4 ]; then
    echo "Parameter '$1' does not look like an IP Address.";
    exit 1;
fi

Then, check that all four parts are numeric:

for OCTET in `echo $IsIP | tr '.' ' '; do
    if ! [[ $OCTET =~ ^[0-9]+$ ]]; then
        echo "Parameter '$1' does not look like an IP Address.";
        exit 1;
    fi
done

Finally check that all four parts are in the range 0 to 255:

for OCTET in `echo $IsIP | tr '.' ' '; do
    if [[ $OCTET -lt 0 || $OCTET -gt 255 ]]; then
        echo "Parameter '$IsIP' does not look like in IP Address (octet '$OCTET' in not in range 0-255).";
    fi
done

So the parameter passed to the script must fulfill the following four criteria:

  1. Contain exactly three dots.
  2. Contain exactly four parts, if broken down by dots.
  3. All four parts are numeric.
  4. All four parts are between 0 and 255.

A Bash function

Here's the entire thing in the form of a Bash function, with an additional comment on what went wrong:

# Verify that the parameter passed is an IP Address:
function is_IP() {
if [ `echo $1 | grep -o '\.' | wc -l` -ne 3 ]; then
        echo "Parameter '$1' does not look like an IP Address (does not contain 3 dots).";
        exit 1;
elif [ `echo $1 | tr '.' ' ' | wc -w` -ne 4 ]; then
        echo "Parameter '$1' does not look like an IP Address (does not contain 4 octets).";
        exit 1;
else
        for OCTET in `echo $1 | tr '.' ' '`; do
                if ! [[ $OCTET =~ ^[0-9]+$ ]]; then
                        echo "Parameter '$1' does not look like in IP Address (octet '$OCTET' is not numeric).";
                        exit 1;
                elif [[ $OCTET -lt 0 || $OCTET -gt 255 ]]; then
                        echo "Parameter '$1' does not look like in IP Address (octet '$OCTET' in not in range 0-255).";
                        exit 1;
                fi
        done
fi

return 0;
}

Example output of the function when saved as a standalone script:

marios@yovan ~ $ ./is_IP 1234
Parameter '1234' does not look like an IP Address (does not contain 3 dots).
marios@yovan ~ $ ./is_IP 1234...
Parameter '1234...' does not look like an IP Address (does not contain 4 octets).
marios@yovan ~ $ ./is_IP 1.2.3.A
Parameter '1.2.3.A' does not look like in IP Address (octet 'A' is not numeric).
marios@yovan ~ $ ./is_IP 1.2.3.300
Parameter '1.2.3.300' does not look like in IP Address (octet '300' in not in range 0-255).
marios@yovan ~ $ ./is_IP 1.2.3.4
marios@yovan ~ $

If someone has any better ways to check this, or improvements on the above, please step forward :)

Fork these scripts on GitHub.

Using Regular Expressions

In an older blog platform that I used, Efstathios Chatzikyriakidis commented and suggested the use of regular expressions, which in retrospect made all the above pretty useless. The expression that I found working best is the one at IP Address regular expression.

Posted on