golang执行ip addr list并获取网卡及其绑定ip

文章介绍了如何在Golang中通过执行Linux的`ipaddrlist`命令来获取系统网卡及绑定的IP地址,因为`net.Interfaces()`无法获取未绑定的IP。作者编写了一个函数`getClientIpsByCmd`来执行命令并解析输出,利用正则表达式匹配IP和MAC地址信息,最后提供了测试案例展示如何获取并显示多个网卡的IP配置详情。
摘要由CSDN通过智能技术生成

最近工作中需要获取系统网卡及绑定ip,方便管理ip,最开始使用golang的

net.Interfaces()

获取不到未绑定ip的网卡,于是打算使用linux ip指令获取,于是记录一下笔记;

1.golang 执行ip add list 获取结果

func getClientIpsByCmd() (ipMap []ClientIpMap, err error) {
	var out bytes.Buffer
	var stdErr bytes.Buffer
	cmd := exec.Command("bash", "-c", `ip addr list`)
	cmd.Stdout = &out
	cmd.Stderr = &stdErr
	err = cmd.Run()
	if err != nil {
		return
	}
	if stdErr.String() != "" {
		err = errors.New(stdErr.String())
		return
	}
	ipMap = spit(out.String())
	return
}

 通过正则匹配解析

type IpMap struct {
	Ip  string
	Mac string
}

type ClientIpMap struct {
	Name string
	Ips  []IpMap
}

func spit(s string) []ClientIpMap {
	cardList := make([]ClientIpMap, 0)
	compile := regexp.MustCompile(`[^a-z0-9][0-9]+:\s+`)
	split := compile.Split(s, -1)
	for i, sp := range split {
		if i == 0 {
			sp = strings.TrimLeft(sp, "1: ")
		}
		ipMap, err := match(sp)
		if err != nil {
			continue
		}
		cardList = append(cardList, ipMap)
	}
	return cardList
}

func match(s1 string) (ClientIpMap, error) {
	compile := regexp.MustCompile(`(?m)(^[a-z0-9\-]+):[\s\S]*([a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2})\s+[brd][\s\S]*`)
	submatch := compile.FindStringSubmatch(s1)

	if len(submatch) < 3 {
		return ClientIpMap{}, errors.New("无效")
	}
	// 匹配ip
	mustCompile := regexp.MustCompile(`(?m)[inet]\s+(\d+\.\d+\.\d+\.\d+)`)
	stringSubmatch := mustCompile.FindAllStringSubmatch(s1, -1)
	ips := make([]IpMap, 0)
	for _, sb := range stringSubmatch {
		if l := len(sb); l > 0 {
			// fmt.Println(sb[l-1])
			ips = append(ips, IpMap{
				Ip:  sb[l-1],
				Mac: submatch[2],
			})
		}
	}

	return ClientIpMap{
		Name: submatch[1],
		Ips:  ips,
	}, nil

}

3.测试

var s = `1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/32 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 0a:8f:d6:1c:a8:00 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.107/24 brd 192.168.2.255 scope global dynamic eth0
       valid_lft 4924sec preferred_lft 4924sec
    inet 192.168.2.132/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::88f:d6ff:fe1c:a800/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 7a:75:c2:49:37:f1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.140/24 brd 192.168.2.255 scope global dynamic eth1
       valid_lft 4659sec preferred_lft 4659sec
    inet 192.168.2.132/32 scope global eth1
       valid_lft forever preferred_lft forever
    inet 192.168.3.132/24 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::7875:c2ff:fe49:37f1/64 scope link
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether b2:5b:10:12:91:db brd ff:ff:ff:ff:ff:ff
5: eth3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 36:a4:d2:43:b6:d4 brd ff:ff:ff:ff:ff:ff`


func Test_GetIPs(t *testing.T) {
	ipMap, err := tools.NewIpServer().GetIps()
	fmt.Printf("res:%-v err:%v", ipMap, err)
}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值