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

如何使用Go语言net包读取Linux下指定虚拟网卡的IP地址

如何单独读取Linux中eth0:2的IP地址?

问题场景

通过ifconfig -a | grep -A2 eth0可以看到网卡eth0及其虚拟子接口的信息:

ifconfig -a | grep -A2 eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 100.180.89.148  netmask 255.255.255.224  broadcast 100.180.89.140
        inet6 fe80::ac16:2dff:fead:a321  prefixlen 64  scopeid 0x20<link>
--
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 100.180.89.150  netmask 255.255.255.255  broadcast 100.180.89.150
        ether cc:16:2d:ad:a3:20  txqueuelen 1000  (Ethernet)
--
eth0:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 100.180.89.151  netmask 255.255.255.255  broadcast 100.180.89.151
        ether ac:16:2d:ad:a3:20  txqueuelen 1000  (Ethernet)
--
eth0:3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 100.180.89.152  netmask 255.255.255.255  broadcast 100.180.89.152
        ether ac:16:2d:ad:a3:20  txqueuelen 1000  (Ethernet)

原Go代码遍历所有接口并输出eth0的所有地址,但输出包含了主接口和所有虚拟子接口的IP:

// nwkIfName = eth0
func networkInterfaces(nwkIfName string) ([]Interfaces, error) {
    ifaces, err := net.Interfaces()
    if err != nil {
        return nil, fmt.Errorf("failed to get network interfaces: %w", err)
    }

    for _, nwIf := range ifaces {
        fmt.Println(nwIf.Name)
        if nwIf.Name == nwkIfName {
            fmt.Println(nwIf.Addrs())
        }
    }
    return nil, nil
}

输出:

[100.180.89.148/27 100.180.89.150/32 100.180.89.151/32 100.180.89.152/32 fe80::ae16:2dff:fead:a320/64] <nil>

现在需要单独读取eth0:2的IP地址。

解决方法

在Linux系统中,eth0:2这类虚拟子接口会被Go标准库的net.Interfaces()识别为独立的网络接口,接口名称就是完整的eth0:2。直接通过匹配接口名称即可获取对应IP。

代码示例:获取指定虚拟子接口的IP

package main

import (
    "fmt"
    "net"
)

// getVirtualInterfaceIP 获取指定虚拟网卡的IP地址
func getVirtualInterfaceIP(ifName string) ([]net.Addr, error) {
    ifaces, err := net.Interfaces()
    if err != nil {
        return nil, fmt.Errorf("获取网络接口失败: %w", err)
    }

    for _, iface := range ifaces {
        // 匹配目标虚拟子接口名称
        if iface.Name == ifName {
            addrs, err := iface.Addrs()
            if err != nil {
                return nil, fmt.Errorf("获取接口%s地址失败: %w", ifName, err)
            }
            return addrs, nil
        }
    }
    return nil, fmt.Errorf("未找到接口%s", ifName)
}

func main() {
    // 传入目标虚拟子接口名称eth0:2
    addrs, err := getVirtualInterfaceIP("eth0:2")
    if err != nil {
        fmt.Println(err)
        return
    }

    // 打印所有IP地址(含IPv4/IPv6)
    for _, addr := range addrs {
        fmt.Println(addr.String())
    }
}

扩展:获取主接口下所有虚拟子接口的IP

如果需要批量获取eth0下所有虚拟子接口(如eth0:1、eth0:2等)的IP,可以通过前缀匹配实现:

package main

import (
    "fmt"
    "net"
    "strings"
)

// getSubInterfaceIPs 获取主接口下所有虚拟子接口的IP
func getSubInterfaceIPs(mainIfName string) (map[string][]net.Addr, error) {
    ifaces, err := net.Interfaces()
    if err != nil {
        return nil, fmt.Errorf("获取网络接口失败: %w", err)
    }

    subIfAddrs := make(map[string][]net.Addr)
    // 构造虚拟子接口名称前缀,如eth0:
    prefix := mainIfName + ":"

    for _, iface := range ifaces {
        if strings.HasPrefix(iface.Name, prefix) {
            addrs, err := iface.Addrs()
            if err != nil {
                return nil, fmt.Errorf("获取接口%s地址失败: %w", iface.Name, err)
            }
            subIfAddrs[iface.Name] = addrs
        }
    }

    if len(subIfAddrs) == 0 {
        return nil, fmt.Errorf("未找到%s的虚拟子接口", mainIfName)
    }
    return subIfAddrs, nil
}

func main() {
    subIfs, err := getSubInterfaceIPs("eth0")
    if err != nil {
        fmt.Println(err)
        return
    }

    // 遍历打印所有虚拟子接口及其IP
    for ifName, addrs := range subIfs {
        fmt.Printf("接口%s的IP地址:\n", ifName)
        for _, addr := range addrs {
            fmt.Printf("  %s\n", addr.String())
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 02:54:24