linux 按mac排序分配网卡名称
需求:设备有6个千电口,2个万兆光口。 需要按类型和接口顺序排列后为它们分配网卡名称(请注意不是mac顺序,而是busid号)。
例如:
00-10-f3-ff-ff-xx-a1-35 --eth0
00-10-f3-ff-ff-xx-a1-36 --eth1
00-10-f3-ff-ff-xx-a1-37 --eth2
00-10-f3-ff-ff-xx-a1-38 --eth3
00-10-f3-ff-ff-xx-a1-39 --eth4
00-10-f3-ff-ff-xx-a1-3a --eth5
00-10-f3-ff-ff-oo-bb-97 --fb10
00-10-f3-ff-ff-oo-bb-97 --fb11
linux版本:centos6.2 32位
起初我是想通过python3的 psutil 模块 可以获得mac地址,然后将mac地址转换成十进制进行排序后对 /etc/udev/rules.d/70-persistent-net.rules 文件修改来实现。也考虑过mac地址不能代表io顺序的问题,最后发现linux命令lspci可以获取对应关系从而放弃这个思路。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #-*-coding:utf8-*- macs = [] interface = {} from psutil import net_if_addrs for k, v in net_if_addrs().items(): for item in v: address = item[ 1 ] if ":" in address and len (address) = = 17 : idkey = address.replace( ':' , '') interface.update({address:( int (address.replace( ':' , ''), 16 ))}) elif "-" in address and len (address) = = 17 : idkey = address.replace( '-' , '') interface.update({address:( int (address.replace( '-' , ''), 16 ))}) for k in sorted (interface,key = interface.__getitem__): print (k,interface[k]) |
lspci -D -n -v |egrep "0200|Device Serial Number"
这里是两个过滤条件,0200代表网卡,包含Device Serial Number行会显示mac地址 。
我的想法是通过busid顺序修改 “/etc/udev/rules.d/70-persistent-net.rules”文件的命名顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [root@new-b3 ~] # lspci -D -n -v |egrep "0200|Number" 0000:02:00.0 0200: 8086:150c Capabilities: [140] Device Serial Number 00-10-f3-ff-ff-xx-a1-35 0000:03:00.0 0200: 8086:150c Capabilities: [140] Device Serial Number 00-10-f3-ff-ff-xx-a1-36 0000:04:00.0 0200: 8086:150c Capabilities: [140] Device Serial Number 00-10-f3-ff-ff-xx-a1-37 0000:05:00.0 0200: 8086:150c Capabilities: [140] Device Serial Number 00-10-f3-ff-ff-xx-a1-38 0000:06:00.0 0200: 8086:150c Capabilities: [140] Device Serial Number 00-10-f3-ff-ff-xx-a1-39 0000:07:00.0 0200: 8086:150c Capabilities: [140] Device Serial Number 00-10-f3-ff-ff-xx-a1-3a 0000:09:00.0 0200: 8086:10fb (rev 01) Capabilities: [140] Device Serial Number 00-10-f3-ff-ff-oo-bb-97 0000:09:00.1 0200: 8086:10fb (rev 01) Capabilities: [140] Device Serial Number 00-10-f3-ff-ff-oo-bb-97 |
python通过 lspci命令 提取busid 和macimport subprocess
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | id = [] mac = [] x = 'lspci -D -n -v | egrep "0200|Serial"' p = subprocess.Popen(x, shell = True , stdout = subprocess.PIPE) out, err = p.communicate() for i in out.splitlines(): if "\t" in i: v1 = i.replace( '''\tCapabilities: [140] Device Serial Number ''' , '') v2 = v1.replace( "-ff-ff" ,"") # 发现lspci提出来的mac地址多了两位 -ff-ff (00-10-f3-ff-ff-oo-bb-97) mac.append(v2.replace( "-" , ":" )) elif "0200:" in i: v1 = i[ 5 : 12 ] v2 = int (v1.split( ":" )[ 0 ]) + int (v1.split( "." )[ - 1 ]) id .append(v2) print ( zip ( id , mac)) <br> |
执行后得到如下结果:
[(2, '00:10:f3:xx:a1:c9'), (3, '00:10:f3:xx:a1:ca'), (4, '00:10:f3:xx:a1:cb'), (5, '00:10:f3:xx:a1:cc'), (6, '00:10:f3:xx:a1:cd'), (7, '00:10:f3:xx:a1:ce'), (9, '00:10:f3:oo:bb:c3'), (10, '00:10:f3:oo:bb:c3')]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import subprocess id = [] mac = [] x = 'lspci -D -n -v | egrep "0200|Serial"' p = subprocess.Popen(x, shell = True , stdout = subprocess.PIPE) out, err = p.communicate() for i in out.splitlines(): if "\t" in i: v1 = i.replace( '''\tCapabilities: [140] Device Serial Number ''' , '') v2 = v1.replace( "-ff-ff" ,"") mac.append(v2.replace( "-" , ":" )) elif "0200:" in i: v1 = i[ 5 : 12 ] v2 = int (v1.split( ":" )[ 0 ]) + int (v1.split( "." )[ - 1 ]) id .append(v2) mac_dic = dict ( zip ( id , mac)) mac_key = sorted (mac_dic) for k in mac_key: print (mac_dic[k] ) |
00:10:f3:xx:a1:35
00:10:f3:xx:a1:36
00:10:f3:xx:a1:37
00:10:f3:xx:a1:38
00:10:f3:xx:a1:39
00:10:f3:xx:a1:3a
00:10:f3:oo:b1:97
00:10:f3:oo:b1:97
这块万兆光口为什么两个口mac地址是相同的?
通过观察这个重复的mac地址最后一位加一就可以了(目前发现的规律是这样)
今天还发现了有个有趣的事情,python在linux下使用 os模块的 system向系统执行命令无法使用 export 添加变量
例如在python shell下 import os模块,然后os.system('export AAA=\"hello!\“')。
执行后在系统的bash下 echo $AAA,会发现没有生效的。
原本想使用 /lib/udev/write_net_rules系统脚本添加的,发现变量不能生效就放弃了。
这些是 export 系统变量的参数,比如 添加个注释、指定网卡名称、指定对应mac地址,执行 /lib/udev/write_net_rules 后就会在 /etc/udev/rules.d/70-persistent-net.rules 文件中添加一条规则。
# MATCHADDR MAC address used for the match
# MATCHID bus_id used for the match
# MATCHDEVID dev_id used for the match
# MATCHDRV driver name used for the match
# MATCHIFTYPE interface type match
# COMMENT comment to add to the generated rule
# INTERFACE_NAME requested name supplied by external tool
# INTERFACE_NEW new interface name returned by rule writer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #!/usr/bin/python #-*-coding:utf8-*- import subprocess import os macs = [] eth_names = [] def lspci_mac(): x = 'lspci -D -n -v | egrep "0200|Serial"' p = subprocess.Popen(x, shell = True , stdout = subprocess.PIPE) out, err = p.communicate() for line in out.splitlines(): if "\t" in line: value = line.replace( "-" , ":" )[ 51 - 9 :].replace( ":ff:ff" ,"") if value in macs: up = str ( hex ( int (value[ - 2 :], 16 ) + 1 )[ - 2 :]) fib = value.replace(value[ - 2 :], str (up)) macs.append(fib) else : macs.append(value) elif "0200:" in line: pass def eth_name(): for id in range ( len (macs)): name = ( "eth" + str ( id )) if id < 6 : eth_names.append(name) elif name = = "eth6" : eth_names.append( "eth10" ) elif name = = "eth7" : eth_names.append( "eth11" ) def out_file(): path = "/etc/udev/rules.d/70-persistent-net.rules" os.system( "rm -rf %s" % (path)) for conf_line in range ( len (macs)): mac_add = macs[conf_line] ethnum = eth_names[conf_line] cfg = '''SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", ATTR{type}=="1", KERNEL=="eth*", NAME="%s"\n''' % (mac_add, ethnum) f = open (path, 'aw' ) f.write(cfg) f.close() if __name__ = = "__main__" : lspci_mac() eth_name() out_file() |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类