如何在shell脚本中检查IP版本(4或6)

时间:2015-07-16 14:48:38

标签: bash shell

我想检查IP是版本4还是版本6。 输入是字符串形式的IP地址。 示例:

IP version 4 --> 1.1.1.1
IP version 6 --> 12:1201::12:15

3 个答案:

答案 0 :(得分:2)

您可以检查字符串是否包含冒号:,然后它是IPv6地址,否则它是IPv4地址:

string='1.1.1.1';

if [[ $string =~ .*:.* ]]
then
  echo "IPv6"
else
  echo "IPv4"
fi

答案 1 :(得分:0)

检查IPV4:

ip='1.1.1.1'
awk -F. 'NF == 4' <<< "$ip"
1.1.1.1

检查IPV6:

ip='12:1201::12:15'
awk -F: 'NF>4' <<< "$ip"
12:1201::12:15

答案 2 :(得分:0)

没有外部呼叫的原生POSIX(无bashisms)解决方案:

#!/bin/sh

if [ "$1" != "${1#*[0-9].[0-9]}" ]; then
  echo IPv4
elif [ "$1" != "${1#*:[0-9a-fA-F]}" ]; then
  echo IPv6
else
  echo "Unrecognized IP format '$1'"
fi

这使用POSIX替换; ${1#*[0-9].[0-9]}是第一个参数,将第一个字符替换为第一个数字 - 点号(因此它与未修改的第一个参数不匹配),它标识IPv4地址,${1#*:[0-9a-fA-F]}是相同的对于冒号十六进制,它标识IPv6地址。为安全起见,我检查两者并对无效IP进行回退。

这不准确,只是速度很快。可以在POSIX shell中进行精确匹配,但它很笨重。

perl

#!/usr/bin/perl

$_ = shift;
chomp;

if (/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ && $1<256 && $2<256 && $3<256 && $4<256)
  { $_ = "IPv4" }
elsif (/^(?!:\w)(?:::?[0-9a-f]{1,4}){1,8}$/i)
  { $_ = "IPv6" }
else
  { $_ = "Unrecognized IP format '$_'" }
print "$_\n";
本地POSIX中的

#!/bin/sh

v4() { [ "$1" -lt 256 ] 2>/dev/null && [ $1 -ge 0 ] && [ $1 != "$2" ]; }

part="${1##*.}"
if v4 $part && v4 ${1%%.*}; then               # test 1 & 4 from 1.2.3.4
  part="${1%$part}"                            # 1.2.3.4 -> 1.2.3
  part="${part#*.}"                            # 1.2.3 -> 2.3
  if v4 "${part%.*}" && v4 "${part#*.}"; then  # tests 2 & 3
    echo IPv4
  fi
# starts with hex, has colon          AND lacks a nonhex/noncolon char
# AND lacks five consecutive hex chars and lacks 9 colons
elif [ "$1" != "${1#[0-9A-Fa-f]*:}" ] && [ "$1" = "${1#*[^0-9A-Fa-f:]}" ] \
&& [ "${1#*[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]}" \
     = "${1#*:*:*:*:*:*:*:*:*:}" ]; then
  echo IPv6
else
  echo "Unrecognized IP format '$1'"
fi