给定 IP 和网络掩码,如何使用 bash 计算网络地址?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15429420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:27:24  来源:igfitidea点击:

Given the IP and netmask, how can I calculate the network address using bash?

bashipsubnetnetmask

提问by Christian

In a bash script I have an IP address like 192.168.1.15 and a netmask like 255.255.0.0. I now want to calculate the start address of this network, that means using the &-operator on both addresses. In the example, the result would be 192.168.0.0. Does someone have something like this ready? I'm looking for an elegant way to deal with ip addresses from bash

在 bash 脚本中,我有一个像 192.168.1.15 这样的 IP 地址和像 255.255.0.0 这样的网络掩码。我现在想计算这个网络的起始地址,这意味着在两个地址上都使用 &-operator。在示例中,结果将是 192.168.0.0。有人准备好这样的东西了吗?我正在寻找一种优雅的方式来处理来自 bash 的 IP 地址

回答by kamituel

Use bitwise &(AND) operator:

使用按位&( AND) 运算符:

$ IFS=. read -r i1 i2 i3 i4 <<< "192.168.1.15"
$ IFS=. read -r m1 m2 m3 m4 <<< "255.255.0.0"
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
192.168.0.0

Example with another IP and mask:

使用另一个 IP 和掩码的示例:

$ IFS=. read -r i1 i2 i3 i4 <<< "10.0.14.97"
$ IFS=. read -r m1 m2 m3 m4 <<< "255.255.255.248"
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
10.0.14.96

回答by ceving

Some Bash functions summarizing all other answers.

一些 Bash 函数总结了所有其他答案。

ip2int()
{
    local a b c d
    { IFS=. read a b c d; } <<< 
    echo $(((((((a << 8) | b) << 8) | c) << 8) | d))
}

int2ip()
{
    local ui32=; shift
    local ip n
    for n in 1 2 3 4; do
        ip=$((ui32 & 0xff))${ip:+.}$ip
        ui32=$((ui32 >> 8))
    done
    echo $ip
}

netmask()
# Example: netmask 24 => 255.255.255.0
{
    local mask=$((0xffffffff << (32 - ))); shift
    int2ip $mask
}


broadcast()
# Example: broadcast 192.0.2.0 24 => 192.0.2.255
{
    local addr=$(ip2int ); shift
    local mask=$((0xffffffff << (32 -))); shift
    int2ip $((addr | ~mask))
}

network()
# Example: network 192.0.2.0 24 => 192.0.2.0
{
    local addr=$(ip2int ); shift
    local mask=$((0xffffffff << (32 -))); shift
    int2ip $((addr & mask))
}

回答by Janci

Just adding an alternative if you have only network prefix available (no netmask):

如果您只有可用的网络前缀(没有网络掩码),只需添加一个替代方案:

IP=10.20.30.240
PREFIX=26
IFS=. read -r i1 i2 i3 i4 <<< $IP
IFS=. read -r xx m1 m2 m3 m4 <<< $(for a in $(seq 1 32); do if [ $(((a - 1) % 8)) -eq 0 ]; then echo -n .; fi; if [ $a -le $PREFIX ]; then echo -n 1; else echo -n 0; fi; done)
printf "%d.%d.%d.%d\n" "$((i1 & (2#$m1)))" "$((i2 & (2#$m2)))" "$((i3 & (2#$m3)))" "$((i4 & (2#$m4)))"

回答by user3126740

Great answer, though minor typo in answer above.

很好的答案,虽然上面的答案有轻微的错字。

$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$(($i2  <-- $i2 should be i2

If anyone knows how to calculate the broadcast address (XOR the network), then calculate the usable nodes between network and broadcast I'd be interested in those next steps. I have to find addresses in a list within a /23.

如果有人知道如何计算广播地址(对网络进行异或),然后计算网络和广播之间的可用节点,我会对接下来的步骤感兴趣。我必须在 /23 中的列表中找到地址。

回答by Mikhail

In addition to @Janci answer

除了@Janci 回答

IP=10.20.30.240
PREFIX=26
IFS=. read -r i1 i2 i3 i4 <<< $IP
D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
binIP=${D2B[$i1]}${D2B[$i2]}${D2B[$i3]}${D2B[$i4]}
binIP0=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((32-$PREFIX))))
# binIP1=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((31-$PREFIX))))1
echo $((2#${binIP0::8})).$((2#${binIP0:8:8})).$((2#${binIP0:16:8})).$((2#${binIP0:24:8}))