如何检查 shell 脚本中 IP 地址的有效性,即在 to 范围0.0.0.0
内255.255.255.255
?
17 回答
如果您使用的是 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,那么您可以使用expr
BRE 而不是 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
有很多方法可以做到这一点。我给你看了几个。
这个单一的正则表达式应该只验证 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
使用 ipcalc(使用 RPM initscripts-9.49.49-1 中的版本包测试)
$ ipcalc -cs 10.10.10.257 && echo vaild_ip || echo invalid_ip
invalid_ip
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 }
这一切的典型解决方案似乎都使用正则表达式,但在我看来,这可能是执行以下操作的更好方法:
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
我调整了所有代码,发现这很有帮助。
#!/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
如果有人仍然通过使用正则表达式来寻找答案,那么下面会起作用 -
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]?$)"
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
我更喜欢使用 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
仍然进行彻底验证的替代版本(这意味着它需要格式正确的 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
我们可以使用“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
#!/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"
您可以根据需要复制以下代码并更改 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
以最简单的形式:-
#!/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
这将涵盖所有场景。
这个怎么样?
# 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 本身的有效性。
可能有用
#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
#!/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