You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Bash中用ip命令获取设备子网掩码并清零非掩码位?

如何在Bash中从网卡IP生成网段格式用于路由配置?

我来分享几个在Bash里实现这个需求的简便方案,都是日常写脚本时常用的思路:


方法一:用ipcalc工具(最直观易读)

很多Linux发行版默认自带ipcalc工具,它专门用来处理IP地址和子网相关的计算,能直接帮你提取网段:

# 第一步:获取网卡eno1的IPv4地址/CIDR格式
ip_cidr=$(ip -f inet -o addr show dev eno1 | awk '{print $4}')

# 第二步:用ipcalc提取对应的网段
network_cidr=$(ipcalc -n "$ip_cidr" | awk -F'=' '{print $2}')

# 第三步:添加路由
ip route add table 128 to "$network_cidr" dev eno1

ipcalc -n会输出类似NETWORK=192.168.1.0/24的结果,用awk拆分就能直接拿到我们需要的网段格式。如果你的系统没装ipcalc,可以用包管理器安装(比如apt install ipcalcyum install ipcalc)。


方法二:纯Awk位运算实现(无需额外工具)

如果是最小化系统没有ipcalc,可以用Awk的位运算直接计算网段,完全不依赖外部工具:

ip -f inet -o addr show dev eno1 | awk -F'[ /]+' '
{
    # 拆分IP为四个字段,提取CIDR前缀
    split($4, ip_parts, ".")
    prefix = $5

    # 计算子网掩码的数值(32位无符号整数)
    mask = 0xffffffff << (32 - prefix)

    # 计算网段的每个部分
    part1 = (ip_parts[1] << 24) & mask
    part2 = (ip_parts[2] << 16) & mask
    part3 = (ip_parts[3] << 8) & mask
    part4 = ip_parts[4] & mask

    # 拼接成标准的网段格式
    network = sprintf("%d.%d.%d.%d/%d",
        part1 >> 24, part2 >> 16, part3 >> 8, part4, prefix)

    # 可以直接在这里执行路由命令,或者先输出验证
    print network
    # system("ip route add table 128 to " network " dev eno1")
}'

这个方法通过位运算把IP地址和子网掩码做按位与,直接得到网段的网络地址,适合环境受限的场景。


方法三:利用ip命令本身的路由信息(最简洁)

其实ip命令已经能直接获取网卡的直连网段,根本不需要自己计算:

# 直接提取eno1的直连网段
network_cidr=$(ip -f inet route show dev eno1 scope link | awk '{print $1}')

# 添加路由
ip route add table 128 to "$network_cidr" dev eno1

ip route show dev eno1 scope link会输出网卡所在的直连网段(比如192.168.1.0/24),直接取第一个字段就是你要的格式。这个方法最省事,前提是网卡已经配置了正常的直连路由(一般正常配置的网卡都会有这条路由)。


个人最推荐方法三,因为它完全依赖系统自带的ip命令,步骤最少也最不容易出错。如果你的场景下方法三不适用,再考虑前两种方案。

内容的提问来源于stack exchange,提问作者user8370684

火山引擎 最新活动