检查IP有效性

时间:2012-12-08 12:18:12

标签: linux shell

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

17 个答案:

答案 0 :(得分:38)

如果你正在使用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

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

答案 1 :(得分:7)

使用ipcalc

$ ipcalc -cs 10.10.10.257 && echo vail_ip || echo invalid_ip
invalid_ip

答案 2 :(得分:5)

我相信这个脚本可以做你想做的事:http://www.linuxjournal.com/content/validating-ip-address-bash-script

编辑,包括以下建议的代码:

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
}

答案 3 :(得分:3)

此单一正则表达式应仅验证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

答案 4 :(得分:2)

我调整了所有代码并发现这有用。

#!/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

答案 5 :(得分: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]?$)"

答案 6 :(得分:2)

我在下面发现了HERE,我觉得非常方便。

#!/bin/bash

# Test an IP address for validity:
# Usage:
#      valid_ip IP_ADDRESS
#      if [[ $? -eq 0 ]]; then echo good; else echo bad; fi
#   OR
#      if valid_ip IP_ADDRESS; then echo good; else echo bad; fi
#
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
}

答案 7 :(得分:1)

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

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

答案 8 :(得分:1)

怎么样?

# 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本身的有效性。

答案 9 :(得分: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"

答案 10 :(得分:0)

我更喜欢使用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

答案 11 :(得分: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

答案 12 :(得分:0)

以最简单的形式:-

mother_data = {
    year: pd.read_csv(f'data/pcbf1h{year}_df.csv', sep=',', header=0)
    for year in [2015, 2016, 2017, 2018]
}

这将涵盖所有情况。

答案 13 :(得分:0)

仍然进行彻底验证的替代版本(这意味着它需要正确格式化的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

答案 14 :(得分:0)

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

答案 15 :(得分:0)

也许有用

require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '10.0'

target 'ProjectcNameApp' do
  config = use_native_modules!

  use_react_native!(:path => config["reactNativePath"])

  target 'ProjectcNameAppTests' do
    inherit! :complete
    # Pods for testing
  end

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  # use_flipper!
  # post_install do |installer|
  #   flipper_post_install(installer)
  # end
end```

答案 16 :(得分:-1)

我知道这是一个“hacky”解决方案,但它对我有用,并且可能会帮助其他人:

ping -c 1 123.123.123.123
if [ "$?" -gt "0" ]; then
    # not connectable
fi

但是,如果 ICMP 在防火墙级别被阻止,这将不起作用。