You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl中优雅统计网卡addr_info的inet/inet6地址数方法

Perl简洁统计网卡IPv4/IPv6地址数量实现

核心计数逻辑

不需要手动遍历索引累加计数器,直接用Perl原生的grep做列表筛选,配合scalar获取列表长度即可完成计数,代码简洁且语义清晰:

# 统计对应family的地址总数
my $ipv4_cnt = scalar grep { $_->{family} eq 'inet' }  @{$nic->{addr_info}};
my $ipv6_cnt = scalar grep { $_->{family} eq 'inet6' } @{$nic->{addr_info}};

实现原理:

  • @{$nic->{addr_info}} 解引用addr_info数组引用,供列表操作遍历
  • grep 代码块判断每个地址条目的family字段,返回所有匹配条件的元素列表
  • scalar 强制切换到标量上下文,直接返回匹配元素的总个数,即对应类型IP的数量

校验逻辑实现

计数完成后直接判断数量阈值,触发对应告警即可:

if ($ipv4_cnt > 1 || $ipv6_cnt > 1) {
    warn "not supported: 网卡". $nic->{ifname}. "存在多个同类型IP地址";
    # 此处插入你的异常处理逻辑
}

可选map实现方式

如果倾向于用map实现,需要注意不匹配的条目要返回空列表而非0,否则会导致计数错误:

# map版本计数,不匹配时返回空列表会被自动忽略
my $ipv4_cnt = scalar map { $_->{family} eq 'inet' ? 1 : () } @{$nic->{addr_info}};

该写法能实现同样效果,但语义上grep本身就是为列表筛选设计的,可读性比map更好,更推荐用grep版本。

完整参考代码

包含从调用ip命令、解码JSON到校验取数的全流程:

use strict;
use warnings;
use JSON::PP;

# 调用ip命令获取JSON格式的网卡信息,不需要分两次调用传-4/-6参数
my $raw = `LC_ALL=C /sbin/ip -j addr show eno1 2>/dev/null`;
my $dev_list = decode_json($raw);
my $nic = $dev_list->[0]; # 指定网卡查询时返回数组只有一个元素

# 统计地址数量
my $ipv4_cnt = scalar grep { $_->{family} eq 'inet' }  @{$nic->{addr_info}};
my $ipv6_cnt = scalar grep { $_->{family} eq 'inet6' } @{$nic->{addr_info}};

# 多IP校验
if ($ipv4_cnt > 1 || $ipv6_cnt > 1) {
    die "not supported";
}

# 提取单IP场景下的地址值
my ($ipv4) = map { $_->{local} } grep { $_->{family} eq 'inet' } @{$nic->{addr_info}};
my ($ipv6) = map { $_->{local} } grep { $_->{family} eq 'inet6' } @{$nic->{addr_info}};

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 15:15:48