4

Quite simply I'd like to verify that a string represents a valid IP address in a bash script. I think like many others I've fallen into the pitfall of trying to do this with a regular expression; while this works well enough for IPv4, IPv6 is more complex (as it supports compression of zeroes) and it's just a complicated and not especially readable solution.

However, unix and linux clearly understand IP addresses well enough, so I'm wondering if there is a better way that I can validate IP addresses in bash? Preferably a reasonably common tool that can be used to do-so.

I'd like to avoid using other languages such as Python to do this, as I am in fact hoping to replace a current solution which is to use PHP's filter_var function. It works, but as with regular expressions, it's introducing a second language where I hope to avoid using one.

Lastly, if there's a solution that can also handle IP address ranges (such as 0.0.0.0-255.255.255.255 or 0.0.0.0/16 etc.) that'd be ideal, but I can handle these myself

  • 1
    Are you looking to handle non-standard cases also? Try ssh 2130706433 to confirm that many 32-bit ints are valid IP addresses. Two 16-bit ints separated by a dot are also valid, etc. – doneal24 Dec 10 '15 at 17:21
  • 2
    IPv6 is more complex (as it supports compression of zeroes). Just IPv6? Try a ping 127.1 and see the result from IP v4 – Hennes Dec 10 '15 at 17:47
  • @DougO'Neal Not sure what you mean by non-standard? Really all I need is to verify that an IP address is valid syntactically (I don't need to verify that it exists, that'll happen elsewhere). @ Hennes I stand corrected, thanks, I suppose it's just something I've never seen with the shorter IPv4 address :) – Haravikk Dec 10 '15 at 22:51
  • Actually, mentioning ping I'm wondering if I could use that? It seems to return status 2 if given an invalid address (like 'foo'), but status 1 if a ping was sent (valid address) but no response was received. Is this reliable enough to use? i.e- status 0 and status 1 = well formed IP? – Haravikk Dec 10 '15 at 22:56
1

Ipcalc can help you:

ipcalc -c <ip-address>
  • Strangely, ipcalc (0.41)'s help has: -c --color Display ANSI color codes (default) and -c --class Just print bit-count-mask of given address. – Stéphane Chazelas Dec 10 '15 at 21:28
  • there must be different versions of ipcalc... Checking my linux-server, I see the same thing, this doesn't look anything like the man-page I linked to! – Rolf Rander Dec 10 '15 at 21:35
  • -c flag doesn't seem to do anything on the version I got via aptitude (on Ubuntu Server 14.04), but it works well enough for IPv4. It doesn't seem to support IPv6 though, at least not the version I've got, are there others? – Haravikk Dec 10 '15 at 22:48
  • The ipcalc packages on Debian based distros differ from RHEL/CentOS - they are different programs with different behavior and different switches. On my Debian -c prints bit-count mask of the given address, while on RHEL -c validates ('checks') the IP address. – bryn Jun 8 '17 at 22:36
1

bash probably lacks direct access to the relevant inet_pton(3) system call, so you'll probably need to call something that does, e.g. sipcalc (which should be in the ports or packages tree for various unix). Higher level languages can probably also get at the inet_pton(3) call, or equivalent, but the details will be language specific, e.g. I've used NetAddr::IP for subnet related code in Perl.

-1

This will do the trick for ipv4

#check for valid IP address if [[ $SourceIP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then echo "valid IP" else echo "Invalid IP: $SourceIP"; exit 0; fi

I'm implementing ipv6 into the script I extracted this from anyway, once I have that done, I'll update this post.

  • That regex is too broad and will accept IP addresses that aren't valid. – Anthony Oct 11 '16 at 22:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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