Bash: Check that string is IP

Assuming that we have a Bash script that accepts a parameter that is supposed 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 :)

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:

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

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.