Linux命令-parted(磁盘分区工具)

parted 是 Linux 中用于 磁盘分区管理 的命令行工具,支持 GPT 和 MBR 分区表,特别适合大容量磁盘(超过 2TB)。

📦 基本语法

bash 复制代码
parted [选项] [设备 [命令 [参数...]]]
# 交互模式:parted /dev/sda
# 非交互模式:parted /dev/sda mkpart primary 0% 100%

🎯 主要功能

  1. 创建分区表:初始化磁盘为 GPT 或 MBR 格式
  2. 创建/删除分区:管理磁盘分区
  3. 调整分区大小:扩展或缩小分区
  4. 复制分区:复制分区结构和数据
  5. 设置分区标志:设置 boot、lvm、raid 等标志
  6. 查看分区信息:显示磁盘和分区详细信息
  7. 文件系统操作:创建/调整文件系统(有限支持)

💡 常用命令

1. 进入交互模式

bash 复制代码
# 进入指定磁盘的交互模式
parted /dev/sda

# 使用特定单位(默认 MB)
parted /dev/sda unit GB

# 显示所有命令帮助
(parted) help

# 查看特定命令帮助
(parted) help mkpart

2. 查看磁盘信息

bash 复制代码
# 查看所有磁盘
parted -l

# 查看指定磁盘信息
parted /dev/sda print

# 查看磁盘型号和容量
parted /dev/sda print devices

# 查看磁盘空闲空间
parted /dev/sda print free

3. 创建分区表

bash 复制代码
# 创建 GPT 分区表(推荐用于新磁盘)
parted /dev/sda mklabel gpt

# 创建 MBR(msdos)分区表
parted /dev/sda mklabel msdos

# 创建其他类型分区表
parted /dev/sda mklabel aix
parted /dev/sda mklabel amiga
parted /dev/sda mklabel bsd
parted /dev/sda mklabel dvh
parted /dev/sda mklabel gpt
parted /dev/sda mklabel loop
parted /dev/sda mklabel mac
parted /dev/sda mklabel pc98
parted /dev/sda mklabel sun

4. 创建分区

bash 复制代码
# 创建主分区(MBR)
parted /dev/sda mkpart primary 1MiB 100GiB

# 创建逻辑分区(MBR,需先有扩展分区)
parted /dev/sda mkpart logical 100GiB 200GiB

# 创建 GPT 分区(无主/逻辑之分)
parted /dev/sda mkpart "data" ext4 0% 50%

# 创建交换分区
parted /dev/sda mkpart "swap" linux-swap 50% 60%

# 创建 EFI 系统分区(ESP)
parted /dev/sda mkpart "EFI" fat32 1MiB 513MiB
parted /dev/sda set 1 esp on

# 使用百分比创建分区
parted /dev/sda mkpart primary ext4 0% 25%
parted /dev/sda mkpart primary ext4 25% 50%
parted /dev/sda mkpart primary ext4 50% 75%
parted /dev/sda mkpart primary ext4 75% 100%

5. 删除分区

bash 复制代码
# 删除指定分区(交互模式)
(parted) rm 1

# 非交互模式删除分区
parted /dev/sda rm 1

# 删除所有分区(危险!)
for i in $(parted /dev/sda print | awk '/^ [0-9]+/ {print $1}'); do
    parted /dev/sda rm $i
done

6. 调整分区大小

bash 复制代码
# 调整分区大小(需要先卸载分区)
parted /dev/sda resizepart 1 150GiB

# 使用百分比调整
parted /dev/sda resizepart 1 50%

# 调整后需要调整文件系统(ext4示例)
resize2fs /dev/sda1

7. 设置分区标志

bash 复制代码
# 设置 boot 标志
parted /dev/sda set 1 boot on

# 设置 lvm 标志
parted /dev/sda set 2 lvm on

# 设置 raid 标志
parted /dev/sda set 3 raid on

# 设置 esp 标志(EFI系统分区)
parted /dev/sda set 1 esp on

# 查看所有可用标志
(parted) help set

# 常用标志:
# boot, root, swap, hidden, raid, lvm, lba, hp-service, palo, prep, msftres
# bios_grub, atvrecv, diag, legacy_boot, msftdata, irst, esp

8. 复制分区

bash 复制代码
# 复制分区表结构
parted /dev/sda unit s print free > partition_layout.txt

# 复制分区(需要相同大小的目标磁盘)
parted /dev/sda unit s
(parted) mkpart primary 2048s 2099199s
(parted) mkpart primary 2099200s 4196351s

# 使用 sfdisk 备份和恢复分区表
sfdisk -d /dev/sda > sda_partition_table.bak
sfdisk /dev/sdb < sda_partition_table.bak

9. 移动分区

bash 复制代码
# 移动分区(需要先卸载)
parted /dev/sda move 1 1MiB 100GiB

# 注意:移动分区可能损坏数据,务必先备份!

10. 文件系统操作

bash 复制代码
# 在分区上创建文件系统
parted /dev/sda mkpart primary ext4 0% 100%
mkfs.ext4 /dev/sda1

# 调整文件系统(需要先调整分区)
parted /dev/sda resizepart 1 200GiB
resize2fs /dev/sda1

# 检查文件系统
e2fsck -f /dev/sda1

🔧 实际应用示例

示例 1:初始化新磁盘(完整流程)

bash 复制代码
#!/bin/bash
# 初始化新磁盘脚本

DISK="/dev/sdb"
LABEL="gpt"
PARTITION_NAME="data"
FILESYSTEM="ext4"
MOUNT_POINT="/mnt/data"

echo "=== 初始化新磁盘: $DISK ==="
echo "分区表类型: $LABEL"
echo "分区名称: $PARTITION_NAME"
echo "文件系统: $FILESYSTEM"
echo "挂载点: $MOUNT_POINT"
echo ""

# 1. 检查磁盘是否存在
if [[ ! -b "$DISK" ]]; then
    echo "错误: 磁盘 $DISK 不存在"
    exit 1
fi

# 2. 确认操作
read -p "警告: 此操作将清除 $DISK 上的所有数据!继续吗?[y/N]: " confirm
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
    echo "操作已取消"
    exit 0
fi

# 3. 卸载所有挂载的分区
echo "卸载已挂载的分区..."
for partition in $(lsblk -lnpo NAME "$DISK" | grep -v "^$DISK$"); do
    if mountpoint -q "/dev/$partition" 2>/dev/null || \
       findmnt "/dev/$partition" >/dev/null 2>&1; then
        echo "卸载 /dev/$partition"
        umount "/dev/$partition" 2>/dev/null
    fi
done

# 4. 清除磁盘签名
echo "清除磁盘签名..."
wipefs -a "$DISK"

# 5. 创建分区表
echo "创建 $LABEL 分区表..."
parted -s "$DISK" mklabel "$LABEL"

# 6. 创建分区(使用整个磁盘)
echo "创建分区..."
if [[ "$LABEL" == "gpt" ]]; then
    parted -s "$DISK" mkpart "$PARTITION_NAME" "$FILESYSTEM" 1MiB 100%
else
    parted -s "$DISK" mkpart primary "$FILESYSTEM" 1MiB 100%
fi

# 7. 设置分区标志(GPT需要)
if [[ "$LABEL" == "gpt" ]]; then
    parted -s "$DISK" set 1 msftdata on
fi

# 8. 刷新内核分区表
echo "刷新分区表..."
partprobe "$DISK"
sleep 2

# 9. 确定分区设备名
PARTITION=""
if [[ -b "${DISK}1" ]]; then
    PARTITION="${DISK}1"
elif [[ -b "${DISK}p1" ]]; then
    PARTITION="${DISK}p1"
else
    echo "错误: 无法确定分区设备名"
    exit 1
fi

echo "分区创建完成: $PARTITION"

# 10. 创建文件系统
echo "创建 $FILESYSTEM 文件系统..."
case "$FILESYSTEM" in
    ext4)
        mkfs.ext4 -F "$PARTITION"
        ;;
    xfs)
        mkfs.xfs -f "$PARTITION"
        ;;
    btrfs)
        mkfs.btrfs -f "$PARTITION"
        ;;
    fat32)
        mkfs.fat -F 32 "$PARTITION"
        ;;
    ntfs)
        mkfs.ntfs -f "$PARTITION"
        ;;
    *)
        echo "错误: 不支持的文件系统: $FILESYSTEM"
        exit 1
        ;;
esac

# 11. 设置卷标
if [[ -n "$PARTITION_NAME" ]]; then
    echo "设置卷标: $PARTITION_NAME"
    case "$FILESYSTEM" in
        ext4)
            e2label "$PARTITION" "$PARTITION_NAME"
            ;;
        xfs)
            xfs_admin -L "$PARTITION_NAME" "$PARTITION"
            ;;
        btrfs)
            btrfs filesystem label "$PARTITION" "$PARTITION_NAME"
            ;;
        fat32|ntfs)
            fatlabel "$PARTITION" "$PARTITION_NAME"
            ;;
    esac
fi

# 12. 创建挂载点并挂载
echo "创建挂载点: $MOUNT_POINT"
mkdir -p "$MOUNT_POINT"

echo "挂载分区..."
mount "$PARTITION" "$MOUNT_POINT"

# 13. 更新 /etc/fstab
echo "更新 /etc/fstab..."
UUID=$(blkid -s UUID -o value "$PARTITION")
if [[ -n "$UUID" ]]; then
    # 备份原 fstab
    cp /etc/fstab /etc/fstab.backup.$(date +%Y%m%d%H%M%S)
    
    # 删除旧的挂载项
    sed -i "\|$MOUNT_POINT|d" /etc/fstab
    sed -i "\|$PARTITION|d" /etc/fstab
    
    # 添加新的挂载项
    case "$FILESYSTEM" in
        ext4)
            echo "UUID=$UUID $MOUNT_POINT ext4 defaults 0 2" >> /etc/fstab
            ;;
        xfs)
            echo "UUID=$UUID $MOUNT_POINT xfs defaults 0 0" >> /etc/fstab
            ;;
        btrfs)
            echo "UUID=$UUID $MOUNT_POINT btrfs defaults 0 0" >> /etc/fstab
            ;;
        fat32)
            echo "UUID=$UUID $MOUNT_POINT vfat defaults,uid=1000,gid=1000,umask=022 0 0" >> /etc/fstab
            ;;
        ntfs)
            echo "UUID=$UUID $MOUNT_POINT ntfs-3g defaults,uid=1000,gid=1000,umask=022 0 0" >> /etc/fstab
            ;;
    esac
    
    echo "已添加到 /etc/fstab"
fi

# 14. 验证挂载
echo "验证挂载..."
df -h "$MOUNT_POINT"
mount | grep "$MOUNT_POINT"

# 15. 设置权限
echo "设置目录权限..."
chmod 755 "$MOUNT_POINT"
chown "$(id -un):$(id -gn)" "$MOUNT_POINT"

echo ""
echo "=== 初始化完成 ==="
echo "磁盘: $DISK"
echo "分区: $PARTITION"
echo "文件系统: $FILESYSTEM"
echo "挂载点: $MOUNT_POINT"
echo "UUID: $UUID"
echo ""
echo "使用以下命令测试:"
echo "  cd $MOUNT_POINT"
echo "  touch test_file"
echo "  ls -la"

示例 2:创建多分区磁盘(GPT)

bash 复制代码
#!/bin/bash
# 创建 GPT 分区磁盘(适合 Linux 系统安装)

DISK="/dev/sdc"
echo "=== 创建 GPT 分区磁盘: $DISK ==="

# 1. 创建 GPT 分区表
echo "1. 创建 GPT 分区表..."
parted -s "$DISK" mklabel gpt

# 2. 创建 EFI 系统分区 (ESP)
echo "2. 创建 EFI 系统分区 (512MB)..."
parted -s "$DISK" mkpart "EFI" fat32 1MiB 513MiB
parted -s "$DISK" set 1 esp on
mkfs.fat -F 32 "${DISK}1"

# 3. 创建 Boot 分区 (1GB)
echo "3. 创建 Boot 分区 (1GB)..."
parted -s "$DISK" mkpart "boot" ext4 513MiB 1.5GiB
mkfs.ext4 "${DISK}2"

# 4. 创建 Swap 分区 (内存大小的 2倍)
MEM_SIZE=$(free -g | awk '/^Mem:/ {print $2}')
SWAP_SIZE=$((MEM_SIZE * 2))
echo "4. 创建 Swap 分区 (${SWAP_SIZE}GB)..."
parted -s "$DISK" mkpart "swap" linux-swap 1.5GiB ${SWAP_SIZE}.5GiB
mkswap "${DISK}3"
swapon "${DISK}3"

# 5. 创建 Root 分区 (50GB)
echo "5. 创建 Root 分区 (50GB)..."
ROOT_START=${SWAP_SIZE}.5
ROOT_END=$((ROOT_START + 50))
parted -s "$DISK" mkpart "root" ext4 ${ROOT_START}GiB ${ROOT_END}GiB
mkfs.ext4 "${DISK}4"

# 6. 创建 Home 分区 (剩余空间)
echo "6. 创建 Home 分区 (剩余空间)..."
parted -s "$DISK" mkpart "home" ext4 ${ROOT_END}GiB 100%
mkfs.ext4 "${DISK}5"

# 7. 显示分区结果
echo ""
echo "=== 分区创建完成 ==="
parted -s "$DISK" print
echo ""
lsblk -f "$DISK"

示例 3:调整分区大小(扩展分区)

bash 复制代码
#!/bin/bash
# 扩展分区大小脚本

PARTITION="/dev/sda2"
NEW_SIZE="500GB"  # 新分区大小
MOUNT_POINT="/home"  # 挂载点(如果是挂载的分区)

echo "=== 扩展分区: $PARTITION ==="
echo "新大小: $NEW_SIZE"
echo "挂载点: $MOUNT_POINT"
echo ""

# 1. 检查分区是否存在
if [[ ! -b "$PARTITION" ]]; then
    echo "错误: 分区 $PARTITION 不存在"
    exit 1
fi

# 2. 获取磁盘设备
DISK=$(echo "$PARTITION" | sed 's/[0-9]*$//')
PARTITION_NUMBER=$(echo "$PARTITION" | grep -o '[0-9]*$')

if [[ -z "$DISK" ]] || [[ -z "$PARTITION_NUMBER" ]]; then
    echo "错误: 无法解析磁盘和分区号"
    exit 1
fi

echo "磁盘: $DISK"
echo "分区号: $PARTITION_NUMBER"
echo ""

# 3. 检查是否挂载
if mount | grep -q "$PARTITION"; then
    echo "分区已挂载,正在卸载..."
    umount "$PARTITION"
    if [[ $? -ne 0 ]]; then
        echo "错误: 无法卸载分区"
        echo "请手动卸载: umount $PARTITION"
        exit 1
    fi
fi

# 4. 检查文件系统(ext4示例)
echo "检查文件系统..."
e2fsck -f "$PARTITION"
if [[ $? -ne 0 ]]; then
    echo "警告: 文件系统检查发现问题"
    read -p "继续吗?[y/N]: " confirm
    if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
        echo "操作已取消"
        exit 1
    fi
fi

# 5. 获取当前分区信息
echo "获取当前分区信息..."
CURRENT_INFO=$(parted -s "$DISK" unit GB print | grep "^ $PARTITION_NUMBER")
if [[ -z "$CURRENT_INFO" ]]; then
    echo "错误: 无法获取分区信息"
    exit 1
fi

echo "当前分区信息: $CURRENT_INFO"

# 6. 获取磁盘空闲空间
FREE_SPACE=$(parted -s "$DISK" unit GB print free | grep "Free Space" | tail -1)
if [[ -z "$FREE_SPACE" ]]; then
    echo "错误: 没有可用空间"
    exit 1
fi

echo "可用空间: $FREE_SPACE"
echo ""

# 7. 确认操作
read -p "确认要扩展分区 $PARTITION 到 $NEW_SIZE 吗?[y/N]: " confirm
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
    echo "操作已取消"
    exit 0
fi

# 8. 调整分区大小
echo "调整分区大小..."
parted -s "$DISK" resizepart "$PARTITION_NUMBER" "$NEW_SIZE"
if [[ $? -ne 0 ]]; then
    echo "错误: 调整分区大小失败"
    exit 1
fi

# 9. 刷新分区表
echo "刷新分区表..."
partprobe "$DISK"
sleep 2

# 10. 扩展文件系统
echo "扩展文件系统..."
resize2fs "$PARTITION"
if [[ $? -ne 0 ]]; then
    echo "错误: 扩展文件系统失败"
    exit 1
fi

# 11. 重新挂载(如果之前有挂载点)
if [[ -n "$MOUNT_POINT" ]] && [[ -d "$MOUNT_POINT" ]]; then
    echo "重新挂载到 $MOUNT_POINT..."
    mount "$PARTITION" "$MOUNT_POINT"
fi

# 12. 验证结果
echo ""
echo "=== 扩展完成 ==="
echo "新分区信息:"
parted -s "$DISK" unit GB print | grep "^ $PARTITION_NUMBER"
echo ""
df -h "$PARTITION" 2>/dev/null || echo "分区未挂载"

示例 4:分区表备份和恢复

bash 复制代码
#!/bin/bash
# 分区表备份和恢复工具

backup_partition_table() {
    local disk="$1"
    local backup_file="${2:-partition_table_$(date +%Y%m%d_%H%M%S).bak}"
    
    if [[ ! -b "$disk" ]]; then
        echo "错误: 磁盘 $disk 不存在"
        return 1
    fi
    
    echo "备份 $disk 的分区表到 $backup_file..."
    
    # 使用 sfdisk 备份
    sfdisk -d "$disk" > "$backup_file"
    
    # 使用 parted 备份
    parted -s "$disk" unit s print > "${backup_file}.parted"
    
    # 备份分区表类型
    parted -s "$disk" print | grep "Partition Table" | awk '{print $3}' > "${backup_file}.label"
    
    echo "备份完成:"
    echo "  - 分区表: $backup_file"
    echo "  - 详细信息: ${backup_file}.parted"
    echo "  - 分区表类型: ${backup_file}.label"
    
    # 显示备份内容
    echo ""
    echo "备份内容预览:"
    cat "$backup_file"
}

restore_partition_table() {
    local disk="$1"
    local backup_file="$2"
    
    if [[ ! -b "$disk" ]]; then
        echo "错误: 磁盘 $disk 不存在"
        return 1
    fi
    
    if [[ ! -f "$backup_file" ]]; then
        echo "错误: 备份文件 $backup_file 不存在"
        return 1
    fi
    
    echo "警告: 这将覆盖 $disk 的现有分区表,所有数据将丢失!"
    read -p "确认恢复吗?[y/N]: " confirm
    if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
        echo "操作已取消"
        return 0
    fi
    
    echo "从 $backup_file 恢复分区表到 $disk..."
    
    # 恢复分区表
    sfdisk "$disk" < "$backup_file"
    
    if [[ $? -eq 0 ]]; then
        echo "分区表恢复成功"
        
        # 刷新内核分区表
        partprobe "$disk"
        
        # 显示恢复后的分区表
        echo ""
        echo "恢复后的分区表:"
        parted -s "$disk" print
    else
        echo "错误: 分区表恢复失败"
        return 1
    fi
}

compare_partition_tables() {
    local disk1="$1"
    local disk2="$2"
    
    if [[ ! -b "$disk1" ]] || [[ ! -b "$disk2" ]]; then
        echo "错误: 磁盘不存在"
        return 1
    fi
    
    echo "比较分区表: $disk1 vs $disk2"
    echo ""
    
    # 获取分区表信息
    info1=$(parted -s "$disk1" unit GB print)
    info2=$(parted -s "$disk2" unit GB print)
    
    echo "=== $disk1 ==="
    echo "$info1"
    echo ""
    echo "=== $disk2 ==="
    echo "$info2"
    echo ""
    
    # 简单比较
    if diff <(echo "$info1") <(echo "$info2") >/dev/null; then
        echo "✅ 分区表相同"
    else
        echo "❌ 分区表不同"
    fi
}

clone_disk_layout() {
    local source_disk="$1"
    local target_disk="$2"
    
    if [[ ! -b "$source_disk" ]] || [[ ! -b "$target_disk" ]]; then
        echo "错误: 磁盘不存在"
        return 1
    fi
    
    if [[ "$source_disk" == "$target_disk" ]]; then
        echo "错误: 源磁盘和目标磁盘不能相同"
        return 1
    fi
    
    # 检查目标磁盘是否更大或相等
    source_size=$(blockdev --getsize64 "$source_disk")
    target_size=$(blockdev --getsize64 "$target_disk")
    
    if [[ $target_size -lt $source_size ]]; then
        echo "警告: 目标磁盘小于源磁盘"
        echo "源磁盘: $((source_size/1024/1024/1024)) GB"
        echo "目标磁盘: $((target_size/1024/1024/1024)) GB"
        read -p "继续吗?[y/N]: " confirm
        if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
            return 1
        fi
    fi
    
    echo "克隆分区表从 $source_disk 到 $target_disk..."
    
    # 备份源磁盘分区表
    temp_file=$(mktemp)
    sfdisk -d "$source_disk" > "$temp_file"
    
    # 恢复分区表到目标磁盘
    sfdisk "$target_disk" < "$temp_file"
    
    # 清理临时文件
    rm -f "$temp_file"
    
    echo "分区表克隆完成"
    
    # 显示结果
    echo ""
    echo "目标磁盘新分区表:"
    parted -s "$target_disk" print
}

# 主程序
case "$1" in
    backup)
        if [[ $# -lt 2 ]]; then
            echo "用法: $0 backup <磁盘> [备份文件]"
            echo "示例: $0 backup /dev/sda /backup/sda_partition.bak"
            exit 1
        fi
        backup_partition_table "$2" "$3"
        ;;
    
    restore)
        if [[ $# -lt 3 ]]; then
            echo "用法: $0 restore <磁盘> <备份文件>"
            echo "示例: $0 restore /dev/sda /backup/sda_partition.bak"
            exit 1
        fi
        restore_partition_table "$2" "$3"
        ;;
    
    compare)
        if [[ $# -lt 3 ]]; then
            echo "用法: $0 compare <磁盘1> <磁盘2>"
            echo "示例: $0 compare /dev/sda /dev/sdb"
            exit 1
        fi
        compare_partition_tables "$2" "$3"
        ;;
    
    clone)
        if [[ $# -lt 3 ]]; then
            echo "用法: $0 clone <源磁盘> <目标磁盘>"
            echo "示例: $0 clone /dev/sda /dev/sdb"
            exit 1
        fi
        clone_disk_layout "$2" "$3"
        ;;
    
    list)
        echo "可用磁盘:"
        lsblk -d -o NAME,SIZE,TYPE,RO,MODEL | grep -v "loop"
        echo ""
        echo "磁盘分区:"
        for disk in $(lsblk -d -o NAME | grep -v "NAME\|loop"); do
            echo "=== /dev/$disk ==="
            parted -s "/dev/$disk" print 2>/dev/null | grep -E "^[[:space:]]*[0-9]+|^Model:|^Disk /"
            echo ""
        done
        ;;
    
    *)
        echo "分区表管理工具"
        echo ""
        echo "用法:"
        echo "  $0 backup <磁盘> [备份文件]     备份分区表"
        echo "  $0 restore <磁盘> <备份文件>    恢复分区表"
        echo "  $0 compare <磁盘1> <磁盘2>      比较分区表"
        echo "  $0 clone <源磁盘> <目标磁盘>    克隆分区表"
        echo "  $0 list                        列出所有磁盘和分区"
        echo ""
        echo "示例:"
        echo "  $0 backup /dev/sda"
        echo "  $0 restore /dev/sda partition.bak"
        echo "  $0 compare /dev/sda /dev/sdb"
        echo "  $0 clone /dev/sda /dev/sdb"
        echo "  $0 list"
        ;;
esac

示例 5:磁盘性能测试脚本

bash 复制代码
#!/bin/bash
# 磁盘性能测试脚本(在分区前后使用)

DISK="$1"
TEST_SIZE="1G"  # 测试文件大小
TEST_DIR="/tmp/disk_test"

if [[ ! -b "$DISK" ]]; then
    echo "用法: $0 <磁盘设备>"
    echo "示例: $0 /dev/sdb"
    exit 1
fi

echo "=== 磁盘性能测试: $DISK ==="
echo "测试大小: $TEST_SIZE"
echo ""

# 创建测试目录
mkdir -p "$TEST_DIR"

# 1. 测试原始磁盘性能(无分区)
echo "1. 测试原始磁盘性能..."
echo "----------------------------------------"

# 写测试
echo "写测试:"
dd if=/dev/zero of="$DISK" bs=1M count=1000 oflag=direct 2>&1 | tail -1

# 读测试(需要先写入数据)
echo "读测试:"
dd if="$DISK" of=/dev/null bs=1M count=1000 iflag=direct 2>&1 | tail -1

echo ""

# 2. 创建测试分区
echo "2. 创建测试分区..."
parted -s "$DISK" mklabel gpt
parted -s "$DISK" mkpart "test" ext4 0% 100%
PARTITION="${DISK}1"
if [[ ! -b "$PARTITION" ]]; then
    PARTITION="${DISK}p1"
fi

# 等待分区设备出现
sleep 2

# 3. 创建文件系统
echo "3. 创建 ext4 文件系统..."
mkfs.ext4 -F "$PARTITION"

# 4. 挂载测试分区
echo "4. 挂载测试分区..."
mount "$PARTITION" "$TEST_DIR"

# 5. 测试分区性能
echo "5. 测试分区性能..."
echo "----------------------------------------"

# 使用 fio 进行综合测试
if command -v fio >/dev/null 2>&1; then
    echo "使用 fio 进行综合性能测试..."
    
    # 顺序写
    echo "顺序写测试:"
    fio --name=seqwrite --rw=write --direct=1 --ioengine=libaio --bs=1M \
        --size="$TEST_SIZE" --numjobs=1 --runtime=60 --group_reporting \
        --directory="$TEST_DIR" 2>/dev/null | grep -E "WRITE:|iops"
    
    # 顺序读
    echo "顺序读测试:"
    fio --name=seqread --rw=read --direct=1 --ioengine=libaio --bs=1M \
        --size="$TEST_SIZE" --numjobs=1 --runtime=60 --group_reporting \
        --directory="$TEST_DIR" 2>/dev/null | grep -E "READ:|iops"
    
    # 随机写
    echo "随机写测试 (4K):"
    fio --name=randwrite --rw=randwrite --direct=1 --ioengine=libaio --bs=4k \
        --size="$TEST_SIZE" --numjobs=4 --runtime=60 --group_reporting \
        --directory="$TEST_DIR" 2>/dev/null | grep -E "WRITE:|iops"
    
    # 随机读
    echo "随机读测试 (4K):"
    fio --name=randread --rw=randread --direct=1 --ioengine=libaio --bs=4k \
        --size="$TEST_SIZE" --numjobs=4 --runtime=60 --group_reporting \
        --directory="$TEST_DIR" 2>/dev/null | grep -E "READ:|iops"
else
    echo "fio 未安装,使用 dd 进行简单测试..."
    
    # 写测试
    echo "写测试:"
    dd if=/dev/zero of="$TEST_DIR/testfile" bs=1M count=1000 oflag=direct 2>&1 | tail -1
    
    # 读测试
    echo "读测试:"
    dd if="$TEST_DIR/testfile" of=/dev/null bs=1M count=1000 iflag=direct 2>&1 | tail -1
    
    # 清理测试文件
    rm -f "$TEST_DIR/testfile"
fi

# 6. 清理
echo ""
echo "6. 清理测试环境..."
umount "$TEST_DIR"
parted -s "$DISK" rm 1
parted -s "$DISK" mklabel gpt  # 恢复为空磁盘

rmdir "$TEST_DIR"

echo ""
echo "=== 测试完成 ==="

📊 常用命令速查表

命令 说明 示例
print 显示分区表 parted /dev/sda print
mklabel 创建分区表 parted /dev/sda mklabel gpt
mkpart 创建分区 parted /dev/sda mkpart primary 0% 100%
rm 删除分区 parted /dev/sda rm 1
resizepart 调整分区大小 parted /dev/sda resizepart 1 200GB
move 移动分区 parted /dev/sda move 1 1MB 100GB
set 设置分区标志 parted /dev/sda set 1 boot on
unit 设置单位 parted /dev/sda unit GB
align-check 检查对齐 parted /dev/sda align-check optimal 1
help 显示帮助 parted help mkpart

⚠️ 注意事项

  1. 数据安全 :分区操作会永久删除数据,操作前务必备份
  2. 卸载分区:调整分区前需要卸载分区
  3. GPT vs MBR:GPT 支持超过 2TB 磁盘和超过 4 个主分区
  4. 对齐优化 :使用 align-check optimal 检查分区对齐
  5. 文件系统:parted 只管理分区,文件系统需要单独创建
  6. LVM/RAID:设置相应标志以便系统识别

💡 使用技巧

  1. 使用百分比0% 表示磁盘开始,100% 表示磁盘结束
  2. 从 1MB 开始:避免对齐问题,分区从 1MB 开始
  3. 脚本模式 :使用 -s 选项进行非交互操作
  4. 单位选择 :使用 unit GBunit MiB 方便阅读
  5. 验证操作 :使用 print 确认分区表正确性

parted 是强大的磁盘分区工具,特别适合大容量磁盘和自动化脚本。对于日常使用,也可以考虑 fdisk(MBR)或 gdisk(GPT)。

相关推荐
艾莉丝努力练剑1 小时前
【QT】界面优化:QSS
linux·运维·开发语言·网络·qt·计算机网络·udp
岭锅锅1 小时前
机房磁控U位资产管理系统:让数据中心资产管理告别粗放式运维
运维·机房·数据机房管理
煜3641 小时前
进程控制知识
linux·运维·服务器
secret_to_me1 小时前
buildRoot编译rootfs实战
linux·c语言·c++·ubuntu·电脑·buildroot
凡人叶枫1 小时前
Effective C++ 条款01:视 C++ 为一个语言联邦
linux·开发语言·c++·effective c++·编程范式·语言联邦
paul_chen211 小时前
CentOS 8 LVM 在线扩容根分区:从 home 安全割让空间(XFS 文件系统)
linux·安全·centos
AOwhisky1 小时前
MySQL 学习笔记(第五期):用户管理与权限控制
linux·运维·数据库·笔记·学习·mysql
kyle~2 小时前
ROS2---零拷贝
linux·c++·机器人·ros2
无限进步_2 小时前
Linux进程创建——fork与vfork深度解析
linux·运维·服务器