基于parted输出识别含boot分区磁盘的Python代码报错排查
问题与解答:定位带boot标识的系统磁盘
问题描述
需要基于parted -l和parted -lm的输出,编写Python代码实现:
- 遍历每个以“Model:”开头的磁盘条目
- 提取磁盘的Model信息、Disk容量信息以及编号为1的分区信息
- 定位包含“boot”标识的系统磁盘
尝试编写的代码如下:
def getMainDisk(): #get disk info using "parted -lm" sample like from outputParted #for loop to find "BYT;" #if found then get next 2 line disk = [] for i, line in enumerate(outputParted.splitlines()): if line.startswith("BYT;"): disk.append([]) #for j loop next 2 line after found BYT; for j in outputParted.splitlines()[i+0:i+1]: disk[i].append(j) #compare disk if have "boot" keyword then append disk[x] to Maindisk # print (Maindisk)
运行时出现错误:
line 265, in getMainDisk disk[i].append(j) IndexError: list index out of range root@pc:~#
附parted -l输出:
Model: ATA KINGSTON SH103S3 (scsi) Disk /dev/sda: 120GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 1049kB 1024MB 1023MB primary ext4 boot 2 1026MB 120GB 119GB extended 5 1026MB 120GB 119GB logical lvm Model: ATA WDC WD10EZEX-00W (scsi) Disk /dev/sdb: 1000GB Sector size (logical/physical): 512B/4096B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 1000GB 1000GB ext4 primary Model: Linux device-mapper (linear) (dm) Disk /dev/mapper/system-root: 103GB Sector size (logical/physical): 512B/512B Partition Table: loop Disk Flags: Number Start End Size File system Flags 1 0.00B 103GB 103GB ext4 Model: Linux device-mapper (linear) (dm) Disk /dev/mapper/system-swap: 16.4GB Sector size (logical/physical): 512B/512B Partition Table: loop Disk Flags: Number Start End Size File system Flags 1 0.00B 16.4GB 16.4GB linux-swap(v1)
附parted -lm输出:
BYT; /dev/sda:120GB:scsi:512:512:msdos:ATA KINGSTON SH103S3:; 1:1049kB:1024MB:1023MB:ext4::boot; 2:1026MB:120GB:119GB:::; 5:1026MB:120GB:119GB:::lvm; BYT; /dev/sdb:1000GB:scsi:512:4096:gpt:ATA WDC WD10EZEX-00W:; 1:1049kB:1000GB:1000GB:ext4:primary:; BYT; /dev/mapper/system-root:103GB:dm:512:512:loop:Linux device-mapper (linear):; 1:0.00B:103GB:103GB:ext4::; BYT; /dev/mapper/system-swap:16.4GB:dm:512:512:loop:Linux device-mapper (linear):; 1:0.00B:16.4GB:16.4GB:linux-swap(v1)::;
错误原因分析
- 索引越界:代码中用原输出的行号
i作为disk列表的索引,但disk是每次遇到"BYT;"才追加一个空列表,其长度等于磁盘的数量,远小于原输出的行号i。比如第二个"BYT;"出现在第6行,此时disk只有1个元素,访问disk[6]必然触发IndexError。 - 内层循环逻辑错误:切片
outputParted.splitlines()[i+0:i+1]仅包含当前行(Python切片左闭右开),根本没有获取后续的磁盘信息行和分区行,无法收集到有效数据。
修改后的代码实现
推荐使用parted -lm的输出(机器可读格式)来解析,逻辑更清晰:
def get_main_disk(output_parted_lm): lines = output_parted_lm.splitlines() disks = [] current_disk = None for line in lines: line = line.strip() if not line: continue # 跳过空行 if line.startswith("BYT;"): # 新磁盘条目开始,先保存上一个磁盘(如果存在) if current_disk is not None: disks.append(current_disk) # 初始化当前磁盘的存储字典 current_disk = { "model": "", "disk_path": "", "capacity": "", "partition_1": {} } elif current_disk is not None: # 分割行内容,去除末尾的分号 parts = line.rstrip(";").split(":") if not parts: continue # 判断是磁盘信息行还是分区行 if parts[0].startswith("/dev/"): # 磁盘信息行:格式为 /dev/sda:120GB:scsi:512:512:msdos:ATA KINGSTON SH103S3: current_disk["disk_path"] = parts[0] current_disk["capacity"] = parts[1] current_disk["model"] = parts[6] elif parts[0].isdigit(): # 分区行,仅处理编号为1的分区 part_num = parts[0] if part_num == "1": current_disk["partition_1"] = { "start": parts[1], "end": parts[2], "size": parts[3], "filesystem": parts[4], "flags": parts[-1] } # 处理最后一个磁盘条目 if current_disk is not None: disks.append(current_disk) # 筛选出包含boot标识的系统磁盘 main_disks = [disk for disk in disks if disk["partition_1"].get("flags") == "boot"] return main_disks # 测试:传入parted -lm的输出字符串 sample_output = """BYT; /dev/sda:120GB:scsi:512:512:msdos:ATA KINGSTON SH103S3:; 1:1049kB:1024MB:1023MB:ext4::boot; 2:1026MB:120GB:119GB:::; 5:1026MB:120GB:119GB:::lvm; BYT; /dev/sdb:1000GB:scsi:512:4096:gpt:ATA WDC WD10EZEX-00W:; 1:1049kB:1000GB:1000GB:ext4:primary:; BYT; /dev/mapper/system-root:103GB:dm:512:512:loop:Linux device-mapper (linear):; 1:0.00B:103GB:103GB:ext4::; BYT; /dev/mapper/system-swap:16.4GB:dm:512:512:loop:Linux device-mapper (linear):; 1:0.00B:16.4GB:16.4GB:linux-swap(v1)::; """ # 执行并打印结果 result = get_main_disk(sample_output) print("带boot标识的系统磁盘:") print(result)
代码说明
- 遍历解析:逐行处理
parted -lm输出,遇到"BYT;"则开始新磁盘的解析 - 数据提取:
- 磁盘信息行:提取设备路径、容量、型号
- 分区行:仅收集编号为1的分区的起始位置、结束位置、大小、文件系统和标志
- 筛选结果:最后过滤出分区1包含"boot"标志的磁盘,即为目标系统磁盘
内容的提问来源于stack exchange,提问作者ammar ibrahim
相关产品推荐
相关产品推荐

