最近遇到一个需要在linux中使用fdisk分区几十块盘,每块盘都要分15个分区的工作,为了提升效率写了一个自动化脚本,希望能帮到和我有一样遭遇的人。
#!/bin/bash
# 检查是否以 root 权限运行
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root." 1>&2
echo "此脚本必须以 root 权限运行。" 1>&2
exit 1
fi
# 检查 fdisk 是否可用
if ! command -v fdisk &> /dev/null; then
echo "Error: fdisk is not installed. Please install fdisk and try again."
echo "错误:fdisk 未安装。请安装 fdisk 并重试。"
exit 1
fi
# 检查 partprobe 是否可用
if ! command -v partprobe &> /dev/null; then
echo "Warning: partprobe is not installed. Please install partprobe to ensure proper partition detection."
echo "警告:partprobe 未安装。请安装 partprobe 以确保正确的分区检测。"
fi
# 初始化 force 标志
FORCE=false
# 解析选项参数
while getopts "f" opt; do
case "$opt" in
f) FORCE=true ;;
*)
echo "Usage: $0 [-f] <device> <size1> <size2> ... <sizeN>"
echo "用法:$0 [-f] <设备> <大小1> <大小2> ... <大小N>"
exit 1
;;
esac
done
shift $((OPTIND - 1)) # 跳过已处理的选项
# 至少需要2个参数(设备名和至少1个分区大小)
if [ "$#" -lt 2 ]; then
echo "Usage: $0 [-f] <device> <size1> <size2> ... <sizeN>"
echo "用法:$0 [-f] <设备> <大小1> <大小2> ... <大小N>"
exit 1
fi
# 获取设备名
DISK=$1
shift
# 检查设备是否存在
if [ ! -b "$DISK" ]; then
echo "Error: Device $DISK does not exist or is not a valid block device."
echo "错误:设备 $DISK 不存在或不是有效的块设备。"
exit 1
fi
# 获取分区大小参数
PARTITIONS=("$@")
# 确保不超过15个分区(3个主分区 + 12个逻辑分区)
if [ "${#PARTITIONS[@]}" -gt 15 ]; then
echo "Error: Too many partitions. A disk can have a maximum of 15 partitions (3 primary + 12 logical)."
echo "错误:分区过多。一个磁盘最多可以有 15 个分区(3 个主分区 + 12 个逻辑分区)。"
exit 1
fi
# 验证分区大小的格式是否正确
for size in "${PARTITIONS[@]}"; do
if ! [[ $size =~ ^[0-9]+[KMG]$ ]]; then
echo "Error: Invalid partition size format: $size."
echo "错误:无效的分区大小格式:$size。"
echo "Partition sizes must be in a format like '10M', '20G', etc."
echo "分区大小必须采用 '10M'、'20G' 等格式。"
exit 1
fi
done
# 检查磁盘是否存在分区
EXISTING_PARTS=$(fdisk -l $DISK 2>/dev/null | grep "^$DISK[0-9]")
if [ -n "$EXISTING_PARTS" ]; then
echo "Warning: The disk $DISK already has partitions:"
echo "警告:磁盘 $DISK 已经有分区:"
fdisk -l $DISK | grep "^$DISK[0-9]"
if [ "$FORCE" = false ]; then
read -p "Do you want to continue and delete all existing partitions? [y/N]: " response
read -p "您是否要继续并删除所有现有分区? [y/N]: " response
case "$response" in
[yY][eE][sS]|[yY])
echo "Deleting all existing partitions on $DISK..."
echo "正在删除 $DISK 上的所有现有分区..."
;;
*)
echo "Aborting script."
echo "正在中止脚本。"
exit 0
;;
esac
else
echo "Force mode enabled. Deleting all existing partitions on $DISK..."
echo "强制模式已启用。正在删除 $DISK 上的所有现有分区..."
fi
# 获取现有分区数量
PART_NUM=$(fdisk -l $DISK | grep "^$DISK" | wc -l)
# 循环删除每个分区
for ((i=PART_NUM; i>0; i--)); do
echo "Deleting partition $i..."
echo "正在删除分区 $i..."
fdisk $DISK <<EOF
d
$i
w
EOF
done
fi
# 创建分区的逻辑
fdisk $DISK <<EOF
o
EOF
# 创建主分区
for i in $(seq 1 3); do
if [ $i -le ${#PARTITIONS[@]} ]; then
echo "Creating primary partition $i with size ${PARTITIONS[$((i-1))]}"
echo "正在创建主分区 $i,大小为 ${PARTITIONS[$((i-1))]}"
fdisk $DISK <<EOF
n
p
$i
+${PARTITIONS[$((i-1))]}
w
EOF
fi
done
# 创建扩展分区(如果需要)
if [ ${#PARTITIONS[@]} -gt 3 ]; then
echo "Creating extended partition..."
echo "正在创建扩展分区..."
fdisk $DISK <<EOF
n
e
4
w
EOF
fi
# 创建逻辑分区
if [ ${#PARTITIONS[@]} -gt 3 ]; then
LOGICAL_PARTITIONS=("${PARTITIONS[@]:3}")
for size in "${LOGICAL_PARTITIONS[@]}"; do
echo "Creating logical partition with size $size"
echo "正在创建逻辑分区,大小为 $size"
fdisk $DISK <<EOF
n
l
+$size
w
EOF
done
fi
# 刷新分区表,通知内核
if command -v partprobe &> /dev/null; then
echo "Running partprobe to refresh partition table..."
echo "正在运行 partprobe 刷新分区表..."
partprobe $DISK
else
echo "Warning: partprobe is not installed. You may need to reboot or run partprobe manually."
echo "警告:partprobe 未安装。您可能需要重新启动或手动运行 partprobe。"
fi
# 显示最终的分区表
fdisk -l $DISK
# 获取磁盘总大小(单位为字节)
TOTAL_DISK_SIZE=$(fdisk -l $DISK 2>/dev/null | grep "Disk $DISK:" | awk '{print $5}')
if [[ -z "$TOTAL_DISK_SIZE" || ! "$TOTAL_DISK_SIZE" =~ ^[0-9]+$ ]]; then
echo "Error: Could not determine the total disk size for $DISK."
echo "错误:无法确定 $DISK 的总磁盘大小。"
exit 1
fi
# 计算所有已用的分区大小
USED_DISK_SIZE=$(fdisk -l $DISK 2>/dev/null | grep Linux| awk '{used+=$4} END {print used}')
if [[ -z "$USED_DISK_SIZE" || ! "$USED_DISK_SIZE" =~ ^[0-9]+$ ]]; then
USED_DISK_SIZE=0 # 如果没有分区,则使用 0
fi
# 比较剩余空间
if [ "$USED_DISK_SIZE" -lt "$TOTAL_DISK_SIZE" ]; then
REMAINING_SPACE=$((TOTAL_DISK_SIZE / 1024 - USED_DISK_SIZE))
# 将字节转换为GB (整数运算)
REMAINING_SPACE_GB=$((REMAINING_SPACE / (1024 * 1024)))
echo "================================================================="
echo "警告: 磁盘上还有未使用的空间: $REMAINING_SPACE_GB GB。"
echo "Warning: There is unused space left on the disk: $REMAINING_SPACE_GB GB."
fi