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

基于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)::;

错误原因分析

  1. 索引越界:代码中用原输出的行号i作为disk列表的索引,但disk是每次遇到"BYT;"才追加一个空列表,其长度等于磁盘的数量,远小于原输出的行号i。比如第二个"BYT;"出现在第6行,此时disk只有1个元素,访问disk[6]必然触发IndexError。
  2. 内层循环逻辑错误:切片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)

代码说明

  1. 遍历解析:逐行处理parted -lm输出,遇到"BYT;"则开始新磁盘的解析
  2. 数据提取:
    • 磁盘信息行:提取设备路径、容量、型号
    • 分区行:仅收集编号为1的分区的起始位置、结束位置、大小、文件系统和标志
  3. 筛选结果:最后过滤出分区1包含"boot"标志的磁盘,即为目标系统磁盘

内容的提问来源于stack exchange,提问作者ammar ibrahim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:25:51