最近工作中需要获取系统网卡及绑定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)
}
结果: