37

如何检查 shell 脚本中 IP 地址的有效性,即在 to 范围0.0.0.0255.255.255.255

4

17 回答 17

73

如果您使用的是 bash,则可以对模式进行简单的正则表达式匹配,而无需验证四边形:

#!/usr/bin/env bash

ip=1.2.3.4

if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  echo "success"
else
  echo "fail"
fi

如果您坚持使用 POSIX shell,那么您可以使用exprBRE 而不是 ERE 来做基本相同的事情:

#!/bin/sh

ip=1.2.3.4

if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then
  echo "success"
else
  echo "fail"
fi

请注意,expr假设您的正则表达式锚定在字符串的左侧,因此^不需要初始值。

如果验证每个四边形是否小于 256 很重要,您显然需要更多代码:

#!/bin/sh

ip=${1:-1.2.3.4}

if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then
  for i in 1 2 3 4; do
    if [ $(echo "$ip" | cut -d. -f$i) -gt 255 ]; then
      echo "fail ($ip)"
      exit 1
    fi
  done
  echo "success ($ip)"
  exit 0
else
  echo "fail ($ip)"
  exit 1
fi

或者甚至可能使用更少的管道:

#!/bin/sh

ip=${1:-1.2.3.4}

if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then
  IFS=.
  set $ip
  for quad in 1 2 3 4; do
    if eval [ \$$quad -gt 255 ]; then
      echo "fail ($ip)"
      exit 1
    fi
  done
  echo "success ($ip)"
  exit 0
else
  echo "fail ($ip)"
  exit 1
fi

或者,如果您的 shell 是 bash,如果您不喜欢算术,则可以使用繁琐的正则表达式进行四边形验证:

#!/usr/bin/env bash

ip=${1:-1.2.3.4}

re='^(0*(1?[0-9]{1,2}|2([0-4][0-9]|5[0-5]))\.){3}'
 re+='0*(1?[0-9]{1,2}|2([‌​0-4][0-9]|5[0-5]))$'

if [[ $ip =~ $re ]]; then
  echo "success"
else
  echo "fail"
fi

这也可以用 BRE 表示,但这比我的手指打字要多。

最后,如果你喜欢把这个功能……放在一个函数中:

#!/usr/bin/env bash

ip=${1:-1.2.3.4}

ipvalid() {
  # Set up local variables
  local ip=${1:-1.2.3.4}
  local IFS=.; local -a a=($ip)
  # Start with a regex format test
  [[ $ip =~ ^[0-9]+(\.[0-9]+){3}$ ]] || return 1
  # Test values of quads
  local quad
  for quad in {0..3}; do
    [[ "${a[$quad]}" -gt 255 ]] && return 1
  done
  return 0
}

if ipvalid "$ip"; then
  echo "success ($ip)"
  exit 0
else
  echo "fail ($ip)"
  exit 1
fi

有很多方法可以做到这一点。我给你看了几个。

于 2012-12-08T15:39:46.860 回答
14

这个单一的正则表达式应该只验证 0.0.0.0 和 255.255.255.255 之间的地址:

#!/bin/bash

ip="1.2.3.4"

if [[ "$ip" =~ ^(([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$ ]]; then
  echo "success"
else
  echo "fail"
fi
于 2016-02-29T14:24:26.623 回答
11

使用 ipcalc(使用 RPM initscripts-9.49.49-1 中的版本包测试)

$ ipcalc -cs 10.10.10.257 && echo vaild_ip || echo invalid_ip
invalid_ip
于 2015-03-27T04:15:15.557 回答
7

Mitch Frazier 在 Bash脚本中验证 IP 地址的脚本 可以完成您想做的事情:

function valid_ip()
{
local  ip=$1
local  stat=1

if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
    stat=$?
fi
return $stat
}
于 2012-12-08T12:21:21.433 回答
4

这一切的典型解决方案似乎都使​​用正则表达式,但在我看来,这可能是执行以下操作的更好方法:

if echo "$ip" | { IFS=. read a b c d e;
    test "$a" -ge 0 && test "$a" -le 255 &&
    test "$b" -ge 0 && test "$b" -le 255 &&
    test "$c" -ge 0 && test "$c" -le 255 &&
    test "$d" -ge 0 && test "$d" -le 255 &&
    test -z "$e"; }; then echo is valid; fi
于 2012-12-09T02:39:58.690 回答
3

我调整了所有代码,发现这很有帮助。

#!/bin/bash

ip="256.10.10.100"

if [[ "$ip" =~ (([01]{,1}[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.([01]{,1}[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.([01]{,1}[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.([01]{,1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]))$ ]]; then
  echo "success"
else
  echo "fail"
fi
于 2017-03-17T16:05:04.387 回答
2

如果有人仍然通过使用正则表达式来寻找答案,那么下面会起作用 -

echo "<sample ip address>"|egrep "(^[0-2][0-5]{1,2}?\.|^[3-9][0-9]?\.)([0-2][0-5]{1,2}?\.|[3-9][0-9]?\.)([0-2][0-5]{1,2}?\.|[3-9][0-9]?\.)([0-2][0-5]{1,2}?$|[3-9][0-9]?$)"
于 2021-02-28T17:28:52.250 回答
1

Perl 有一个很棒的模块Regexp::Common用于验证各种事情:

perl -MRegexp::Common=net -e 'exit(shift() !~ /^$RE{net}{IPv4}$/)' $ipaddr

您可能需要sudo cpan install Regexp::Common

我将它包装在一个函数中:

valid_ip() {
  perl -MRegexp::Common=net -e 'exit(shift() !~ /^$RE{net}{IPv4}$/)' "$1"
}

if valid_ip 123.234.345.456; then
  echo OK
else
  echo INVALID
fi
于 2012-12-08T19:16:00.570 回答
1

我更喜欢使用 ipcalc 来执行此操作,只要我的脚本不必是可移植的。

ipcalc 1.1.1.355                                                                         
INVALID ADDRESS: 1.1.1.355

Address:   192.168.1.1          11000000.10101000.00000001. 00000001
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   192.168.1.0/24       11000000.10101000.00000001. 00000000
HostMin:   192.168.1.1          11000000.10101000.00000001. 00000001
HostMax:   192.168.1.254        11000000.10101000.00000001. 11111110
Broadcast: 192.168.1.255        11000000.10101000.00000001. 11111111
Hosts/Net: 254                   Class C, Private Internet

这里有一个很棒的页面展示了如何在脚本等中使用它: SleeplessBeastie's Notes

于 2018-12-31T15:18:12.773 回答
1

仍然进行彻底验证的替代版本(这意味着它需要格式正确的 IP 地址,并且每个象限都在允许的值范围内,即 0-255)。在 GNU bash 4.4.20 (Linux Mint 19.3) 上运行良好;在其他地方没有任何承诺,但只要你有 bash 4 就可以了。

初始格式检查正则表达式是从上面的 shannonman / Mitch Frazier 答案中借用的;其余的是我自己的。

    function isValidIpAddr() {
        # return code only version
        local ipaddr="$1";
        [[ ! $ipaddr =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && return 1;
        for quad in $(echo "${ipaddr//./ }"); do
            (( $quad >= 0 && $quad <= 255 )) && continue;
            return 1;
        done
    }
    function validateIpAddr() {
        # return code + output version
        local ipaddr="$1";
        local errmsg="ERROR: $1 is not a valid IP address";
        [[ ! $ipaddr =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && echo "$errmsg" && return 1;
        for quad in $(echo "${ipaddr//./ }"); do
            (( $quad >= 0 && $quad <= 255 )) && continue;
            echo "$errmsg";
            return 1;
        done
        echo "SUCCESS: $1 is a valid IP address";
    }

    $ isValidIpAddr '192.168.0.1'
    $ echo "$?"
    0

    $ isValidIpAddr '192.168.0.256'
    $ echo "$?"
    1

    $ validateIpAddr '12.1.10.191'
    SUCCESS: 12.1.10.191 is a valid IP address

    $ validateIpAddr '1.1.1.127'
    SUCCESS: 1.1.1.127 is a valid IP address

    $ validateIpAddr '1.1.1.1337'
    ERROR: 1.1.1.1337 is not a valid IP address
于 2020-02-16T03:10:54.080 回答
1

我们可以使用“ip route save”来进行检查。

valid_addrmask() 
{
    ip -4 route save match $1 > /dev/null 2>&1
}

$ valid_addrmask 255.255.255.255 && echo "is valid" || echo "is not valid"
is valid
$ valid_addrmask 255.255.255.355 && echo "is valid" || echo "is not valid"
is not valid
于 2021-12-12T06:30:43.243 回答
0
#!/bin/bash
read -p " ip: " req_ipadr
#
ip_full=$(echo $req_ipadr | sed -n 's/^\(\(\([1-9][0-9]\?\|[1][0-9]\{0,2\}\|[2][0-4][0-9]\|[2][5][0-4]\)\.\)\{3\}\([1-9][0-9]\?\|[1][0-9]\{0,2\}\|[2][0-4][0-9]\|[2][5][0-4]\)\)$/\1/p')
#
[ "$ip_full" != "" ] && echo "$req_ipadr vaild ip" || echo "$req_ipadr invaild ip"
于 2016-07-26T15:02:28.230 回答
0

您可以根据需要复制以下代码并更改 if else 控件的主体

function checkIP(){
echo "Checking IP Integrity"    
ip=$1
byte1=`echo "$ip"|xargs|cut -d "." -f1`
byte2=`echo "$ip"|xargs|cut -d "." -f2`
byte3=`echo "$ip"|xargs|cut -d "." -f3`
byte4=`echo "$ip"|xargs|cut -d "." -f4`


if [[  $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$  && $byte1 -ge 0 && $byte1 -le 255 && $byte2 -ge 0 && $byte2 -le 255 && $byte3 -ge 0 && $byte3 -le 255 && $byte4 -ge 0 && $byte4 -le 255 ]]
then
    echo "IP is correct"
else
    echo "This Doesn't look like a valid IP Address : $ip" 
fi
}
checkIP $myIP 

使用存储在名为 myIP 的变量中的 IP 地址调用该方法。

$ip =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ -这部分确保 IP 由 4 个由点 (.) 分隔的块组成,但这里的每个块都允许范围为 0 - 999

由于每个块的所需范围是 0 - 255,因此可以确保可以使用下面的行。

$byte1 -ge 0 && $byte1 -le 255 && $byte2 -ge 0 && $byte2 -le 255 && $byte3 -ge 0 && $byte3 -le 255 && $byte4 -ge 0 && $byte4 -le 255

于 2019-05-10T13:58:50.960 回答
0

以最简单的形式:-

#!/bin/bash
while true;
do
read -p "Enter a ip: " IP
echo "${IP}" > ip.txt
OCT1=$(cat ip.txt | awk -F "." '{print $1}')
OCT2=$(cat ip.txt | awk -F "." '{print $2}')
OCT3=$(cat ip.txt | awk -F "." '{print $3}')
OCT4=$(cat ip.txt | awk -F "." '{print $4}')
REGEX_IP='^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$'
if [[ ${IP} =~ ${REGEX_IP} ]]
then
    if [[ ${OCT1} -gt 255 || ${OCT2} -gt 255 || ${OCT3} -gt 255 || ${OCT4} -gt 255 ]]
        then
        echo "Please enter a valid ip"
        continue
        fi

break
else
        echo "Please enter a valid ip"
        continue
fi
done

这将涵盖所有场景。

于 2019-12-17T04:07:11.263 回答
0

这个怎么样?

# ip route get 10.10.10.100 > /dev/null 2>&1  ; echo $?
0

# ip route get 10.10.10.300 > /dev/null 2>&1  ; echo $?
1

由于“ip”命令检查 IP 本身的有效性。

于 2020-04-19T10:12:35.647 回答
0

可能有用

#this script verify either a ip address is valid or not as well as public or local ip
#$1 means supplied first argument
ip=$(echo $1 | gawk '/^[0-9]{1,3}\.[0-9]{1,3}+\.[0-9]{1,3}+\.[0-9]{1,3}$/{print $0}')
#regular expression to match pattarn from 0.0.0.0 to 999.999.999.999 address

ip1=$(echo $ip | gawk -F. '{print $1}')
ip2=$(echo $ip | gawk -F. '{print $2}')
ip3=$(echo $ip | gawk -F. '{print $3}')
ip4=$(echo $ip | gawk -F. '{print $4}')

echo "Your ip is : $ip1.$ip2.$ip3.$ip4" #extract four number from the address

#To rectify original ip range 0-255 
if [[ $ip1 -le 255 && $ip1 -ne 0 && $ip2 -ne 0 &&  $ip2 -le 255 && $ip3 -ne 0 && $ip3 -le 255 && $ip4 -ne 0 && $ip4 -le 255 ]]
then
    echo "This is a valid ip address"
else
    echo "This is not a valid ip address"
fi

if [[ $ip1 -eq 198 ]]
then
    echo "It may be a local ip address"
else
    echo "It may be a public ip address"
fi
于 2021-05-05T10:00:41.913 回答
0
#!/bin/bash

IP="172.200.22.33.88"
p=`echo $IP | tr '.' '\n' | wc -l`
echo $p
IFS=.
set $IP
echo $IP
a=$1
b=$2
c=$3
d=$4


if [[ $p == 4 &&  $a -lt 255 && $b -lt 255 && $c -lt 255 && $d -lt 255 ]]

then

echo " THIS is Valid IP "

else

echo "THIS IS NOT VALID IP ADDRESS"

fi
于 2022-01-20T11:11:02.330 回答