Linux磁盘挂载助手:一键管理磁盘分区与挂载
Linux磁盘挂载助手:一键管理磁盘分区与挂载
简介
Linux磁盘挂载助手是一款功能强大的跨平台磁盘管理工具,支持Debian、Ubuntu、CentOS、RHEL、Rocky Linux、AlmaLinux、Arch Linux、Manjaro、openSUSE等主流Linux发行版。无论您是Linux新手还是资深管理员,这个脚本都能简化磁盘管理流程,提供安全、直观的操作界面。
主要功能
- ✅ 全自动磁盘检测 - 智能识别系统所有磁盘和分区
- ✅ 多种文件系统支持 - ext4、xfs、ext3、btrfs、NTFS、FAT32
- ✅ 分区表管理 - 支持GPT和MBR分区表
- ✅ 一键挂载/卸载 - 简化挂载流程,自动配置fstab
- ✅ 分区管理 - 创建、格式化、删除分区
- ✅ 安全保护 - 避免误操作系统关键分区
- ✅ 跨平台兼容 - 自动适配不同发行版的包管理器
快速开始
1. 下载并运行脚本
# 方法一:直接运行(推荐一键运行)
bash <(curl -s http://disk.6wd.cn/mount-disk.sh)
# 方法二:下载后运行
curl -s http://disk.6wd.cn/mount-disk.sh -o mount.sh
sudo bash mount.sh
2. 主菜单界面
运行脚本后,您将看到清晰的图形化界面:
#!/bin/bash
# 磁盘挂载助手 - 跨平台版 v6.1
# 支持:Debian/Ubuntu/CentOS/RHEL/Rocky/Alma/Arch/Manjaro/openSUSE
# 支持:GPT/MBR分区表,多种文件系统,自动包管理检测
# 新增:删除分区/分区表功能
# 使用方法: curl -s https://your-domain.com/mount-universal.sh | sudo bash
set -e
# 颜色定义
if command -v tput > /dev/null 2>&1; then
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
BLUE=$(tput setaf 4)
PURPLE=$(tput setaf 5)
CYAN=$(tput setaf 6)
WHITE=$(tput setaf 7)
BOLD=$(tput bold)
RESET=$(tput sgr0)
else
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
BOLD='\033[1m'
RESET='\033[0m'
fi
# 全局变量
FORMAT_RESULT=""
PKG_MANAGER=""
PARTED_AVAILABLE=false
FDISK_AVAILABLE=false
PARTITION_TOOL=""
GPT_SUPPORT=true
MBR_SUPPORT=true
SYS_INFO=""
CONTAINER_ENV=false
RESTART_SCRIPT=false # 新增:标记是否需要重启脚本
# 系统兼容性检查
check_system_compatibility() {
echo -e "${CYAN}${BOLD}系统兼容性检查...${RESET}"
echo ""
# 检查操作系统
if [ -f /etc/os-release ]; then
. /etc/os-release
SYS_INFO="$PRETTY_NAME"
echo -e " ${WHITE}系统:${RESET} $PRETTY_NAME"
elif [ -f /etc/redhat-release ]; then
SYS_INFO=$(cat /etc/redhat-release)
echo -e " ${WHITE}系统:${RESET} $SYS_INFO"
elif [ -f /etc/arch-release ]; then
SYS_INFO="Arch Linux"
echo -e " ${WHITE}系统:${RESET} Arch Linux"
else
SYS_INFO="Unknown Linux"
echo -e " ${WHITE}系统:${RESET} 未知Linux发行版"
fi
# 检查内核
echo -e " ${WHITE}内核:${RESET} $(uname -r)"
# 检查架构
local arch=$(uname -m)
echo -e " ${WHITE}架构:${RESET} $arch"
# 检查是否在容器中
if [ -f /.dockerenv ] || grep -q docker /proc/1/cgroup 2>/dev/null || grep -q kubepods /proc/1/cgroup 2>/dev/null; then
CONTAINER_ENV=true
echo -e " ${WHITE}环境:${RESET} ${YELLOW}容器环境${RESET}"
else
echo -e " ${WHITE}环境:${RESET} 物理机/虚拟机"
fi
# 检查可用工具
if command -v parted > /dev/null 2>&1; then
PARTED_AVAILABLE=true
PARTITION_TOOL="parted"
echo -e " ${WHITE}分区工具:${RESET} ${GREEN}parted${RESET} (支持GPT/MBR)"
fi
if command -v fdisk > /dev/null 2>&1; then
FDISK_AVAILABLE=true
if [ -z "$PARTITION_TOOL" ]; then
PARTITION_TOOL="fdisk"
fi
echo -e " ${WHITE}分区工具:${RESET} ${GREEN}fdisk${RESET} (主要MBR,新版支持GPT)"
fi
if [ -z "$PARTITION_TOOL" ]; then
echo -e " ${WHITE}分区工具:${RESET} ${RED}未找到${RESET}"
fi
# 检查包管理器
detect_package_manager
echo -e " ${WHITE}包管理器:${RESET} ${CYAN}$PKG_MANAGER${RESET}"
echo ""
# 检查是否支持GPT
local kernel_version=$(uname -r | cut -d. -f1-2)
if [ "$(echo "$kernel_version >= 2.6" | bc 2>/dev/null || echo 0)" -eq 1 ] || [ "$(echo "$kernel_version" | awk -F. '{print $1$2}')" -ge 26 ]; then
GPT_SUPPORT=true
else
GPT_SUPPORT=false
echo -e "${YELLOW}[!]${RESET} 内核版本较旧,可能不支持GPT分区表"
fi
# 最低要求检查
if ! command -v lsblk > /dev/null 2>&1; then
echo -e "${RED}[✗]${RESET} 缺少必要工具: lsblk"
exit 1
fi
if ! command -v blkid > /dev/null 2>&1; then
echo -e "${RED}[✗]${RESET} 缺少必要工具: blkid"
exit 1
fi
echo -e "${GREEN}[✓]${RESET} 系统兼容性检查通过"
echo ""
}
# 检测包管理器
detect_package_manager() {
if command -v apt > /dev/null 2>&1; then
PKG_MANAGER="apt"
elif command -v apt-get > /dev/null 2>&1; then
PKG_MANAGER="apt-get"
elif command -v yum > /dev/null 2>&1; then
PKG_MANAGER="yum"
elif command -v dnf > /dev/null 2>&1; then
PKG_MANAGER="dnf"
elif command -v pacman > /dev/null 2>&1; then
PKG_MANAGER="pacman"
elif command -v zypper > /dev/null 2>&1; then
PKG_MANAGER="zypper"
elif command -v emerge > /dev/null 2>&1; then
PKG_MANAGER="emerge"
elif command -v apk > /dev/null 2>&1; then
PKG_MANAGER="apk"
else
PKG_MANAGER="unknown"
fi
}
# 通用安装包函数
install_package() {
local package=$1
local description=${2:-$package}
if command -v "$package" > /dev/null 2>&1; then
return 0
fi
echo -e "${YELLOW}[!]${RESET} 正在安装 $description..."
case $PKG_MANAGER in
apt|apt-get)
$PKG_MANAGER update > /dev/null 2>&1
$PKG_MANAGER install -y "$package" > /dev/null 2>&1
;;
yum|dnf)
$PKG_MANAGER install -y "$package" > /dev/null 2>&1
;;
pacman)
pacman -S --noconfirm "$package" > /dev/null 2>&1
;;
zypper)
zypper install -y "$package" > /dev/null 2>&1
;;
emerge)
emerge --quiet "$package" > /dev/null 2>&1
;;
apk)
apk add --quiet "$package" > /dev/null 2>&1
;;
*)
echo -e "${RED}[✗]${RESET} 无法自动安装 $package,请手动安装"
return 1
;;
esac
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} $description 安装成功"
return 0
else
echo -e "${RED}[✗]${RESET} $description 安装失败"
return 1
fi
}
# 检查root权限
check_root() {
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}╔══════════════════════════════════════════╗${RESET}"
echo -e "${RED}║ 权限错误 ║${RESET}"
echo -e "${RED}╠══════════════════════════════════════════╣${RESET}"
echo -e "${RED}║ 此脚本需要root权限运行 ║${RESET}"
echo -e "${RED}║ ║${RESET}"
echo -e "${RED}║ 请使用: ${GREEN}sudo bash \$0${RED} ║${RESET}"
echo -e "${RED}╚══════════════════════════════════════════╝${RESET}"
exit 1
fi
}
# 显示系统信息
show_system_info() {
clear
echo -e "${PURPLE}╔══════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${PURPLE}║ 磁盘挂载助手 - 跨平台版 v6.1 ║${RESET}"
echo -e "${PURPLE}║ 支持:挂载 / 卸载 / 格式化 / 删除分区 / 删除分区表 ║${RESET}"
echo -e "${PURPLE}║ 兼容:Debian/Ubuntu/CentOS/RHEL/Arch/openSUSE等主流发行版 ║${RESET}"
echo -e "${PURPLE}╚══════════════════════════════════════════════════════════════╝${RESET}"
echo ""
echo -e "${CYAN}${BOLD}系统信息:${RESET}"
echo -e " ${WHITE}系统:${RESET} $SYS_INFO"
echo -e " ${WHITE}内核:${RESET} $(uname -r)"
echo -e " ${WHITE}主机:${RESET} $(hostname)"
echo ""
}
# 获取磁盘状态
get_disk_status() {
local disk=$1
local disk_path="/dev/$disk"
local disk_mount=$(lsblk -d -n -o MOUNTPOINT "$disk_path" 2>/dev/null | xargs)
local partitions=$(lsblk -l -n -o NAME,MOUNTPOINT | grep "^${disk}[0-9]" | awk '{print $2}' | xargs)
if [ -n "$disk_mount" ]; then
echo "disk_mounted"
elif [ -z "$partitions" ]; then
echo "no_mounts"
else
local all_mounted=true
local some_mounted=false
while IFS= read -r line; do
local part_mount=$(echo "$line" | awk '{print $2}' | xargs)
if [ -n "$part_mount" ]; then
some_mounted=true
else
all_mounted=false
fi
done <<< "$(lsblk -l -n -o NAME,MOUNTPOINT | grep "^${disk}[0-9]")"
if $all_mounted && $some_mounted; then
echo "all_partitions_mounted"
elif $some_mounted; then
echo "some_partitions_mounted"
else
echo "no_mounts"
fi
fi
}
# 显示磁盘状态颜色
get_disk_status_color() {
local status=$1
case $status in
"disk_mounted")
echo "${GREEN}磁盘已挂载${RESET}"
;;
"all_partitions_mounted")
echo "${GREEN}全部分区已挂载${RESET}"
;;
"some_partitions_mounted")
echo "${YELLOW}部分分区已挂载${RESET}"
;;
"no_mounts")
echo "${RED}未挂载${RESET}"
;;
*)
echo "${RED}未知${RESET}"
;;
esac
}
# 显示磁盘信息
show_disk_info() {
echo -e "${CYAN}${BOLD}系统磁盘状态:${RESET}"
echo ""
echo -e "${BLUE}┌─────────────────────────────────────────────────────────────┐${RESET}"
printf "${BLUE}│%-12s │ %-8s │ %-10s │ %-20s│${RESET}\n" "设备" "容量" "类型" "状态"
echo -e "${BLUE}├─────────────────────────────────────────────────────────────┤${RESET}"
local disks=$(lsblk -d -n -o NAME | grep -vE '^loop|^sr' | sort)
for disk in $disks; do
local disk_path="/dev/$disk"
local size=$(lsblk -d -n -o SIZE "$disk_path" | xargs)
local status=$(get_disk_status "$disk")
local status_display=$(get_disk_status_color "$status")
printf "│${GREEN}%-12s${RESET}│${CYAN}%9s${RESET}│${WHITE}%11s${RESET}│ %-20s│\n" \
"$disk_path" "$size" "disk" "$status_display"
local partitions=$(lsblk -l -n -o NAME,SIZE,FSTYPE,MOUNTPOINT | grep "^${disk}[0-9]" | sort)
if [ -n "$partitions" ]; then
while IFS= read -r part_line; do
local part_name=$(echo "$part_line" | awk '{print $1}')
local part_size=$(echo "$part_line" | awk '{print $2}' | xargs)
local part_fstype=$(echo "$part_line" | awk '{print $3}' | xargs)
local part_mount=$(echo "$part_line" | awk '{print $4}' | xargs)
local part_path="/dev/$part_name"
if [ -n "$part_mount" ]; then
printf "│ ${YELLOW}└─%-10s${RESET}│${CYAN}%9s${RESET}│${WHITE}%11s${RESET}│ ${GREEN}%-20s${RESET}│\n" \
"$part_path" "$part_size" "part" "$part_mount"
else
if [ -n "$part_fstype" ] && [ "$part_fstype" != "swap" ]; then
printf "│ ${YELLOW}└─%-10s${RESET}│${CYAN}%9s${RESET}│${WHITE}%11s${RESET}│ ${YELLOW}%-20s${RESET}│\n" \
"$part_path" "$part_size" "part" "可挂载"
else
printf "│ ${YELLOW}└─%-10s${RESET}│${CYAN}%9s${RESET}│${WHITE}%11s${RESET}│ %-20s│\n" \
"$part_path" "$part_size" "part" "-"
fi
fi
done <<< "$partitions"
echo -e "${BLUE}├─────────────────────────────────────────────────────────────┤${RESET}"
fi
done
echo -e "${BLUE}└─────────────────────────────────────────────────────────────┘${RESET}"
echo ""
}
# 显示可用的挂载设备列表
show_available_mount_devices() {
echo -e "${CYAN}${BOLD}可挂载的设备列表:${RESET}"
echo ""
local index=1
declare -gA device_map
device_map=()
while IFS= read -r line; do
local fields=($line)
local name="${fields[0]}"
local type="${fields[1]}"
local size="${fields[2]}"
local fstype="${fields[3]}"
local mountpoint="${fields[4]}"
if [ "$type" = "part" ] && [ "$fstype" != "swap" ] && [ -z "$mountpoint" ] && [ -b "/dev/$name" ]; then
device_map[$index]="/dev/$name"
if [ -z "$fstype" ] || [ "$fstype" = "" ]; then
fstype_display="${RED}无文件系统${RESET}"
else
fstype_display="${YELLOW}$fstype${RESET}"
fi
printf " ${GREEN}%2d${RESET}) ${BLUE}%-12s${RESET} ${CYAN}%8s${RESET} %s\n" \
"$index" "/dev/$name" "$size" "$fstype_display"
index=$((index+1))
fi
done < <(lsblk -l -n -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT | sort -V)
# 显示未分区的磁盘
while IFS= read -r line; do
local fields=($line)
local disk="${fields[0]}"
local type="${fields[1]}"
local size="${fields[2]}"
if [ "$type" = "disk" ] && [ -b "/dev/$disk" ]; then
local has_partitions=$(lsblk -l -n -o NAME,TYPE | grep "^${disk}[0-9]" | grep -c "part")
if [ "$has_partitions" -eq 0 ]; then
device_map[$index]="/dev/$disk"
printf " ${GREEN}%2d${RESET}) ${BLUE}%-12s${RESET} ${CYAN}%8s${RESET} ${RED}未分区${RESET}\n" \
"$index" "/dev/$disk" "$size"
index=$((index+1))
fi
fi
done < <(lsblk -d -n -o NAME,TYPE,SIZE | grep -vE '^loop|^sr' | sort -V)
if [ $index -eq 1 ]; then
echo -e " ${YELLOW}没有找到可挂载的设备${RESET}"
echo ""
return 1
fi
echo ""
return 0
}
# 显示已挂载的设备列表
show_mounted_devices() {
echo -e "${CYAN}${BOLD}已挂载的设备列表:${RESET}"
echo ""
local index=1
declare -gA mounted_device_map
mounted_device_map=()
while IFS= read -r line; do
local fields=($line)
local name="${fields[0]}"
local type="${fields[1]}"
local size="${fields[2]}"
local fstype="${fields[3]}"
local mountpoint="${fields[4]}"
if [ "$type" = "part" ] && [ "$fstype" != "swap" ] && [ -n "$mountpoint" ] && [ "$mountpoint" != "/" ] && [ -b "/dev/$name" ]; then
mounted_device_map[$index]="/dev/$name|$mountpoint"
printf " ${GREEN}%2d${RESET}) ${BLUE}%-12s${RESET} ${CYAN}%8s${RESET} ${YELLOW}挂载点: $mountpoint${RESET}\n" \
"$index" "/dev/$name" "$size"
index=$((index+1))
fi
done < <(lsblk -l -n -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT | sort -V)
if [ $index -eq 1 ]; then
echo -e " ${YELLOW}没有找到已挂载的可卸载设备${RESET}"
echo ""
return 1
fi
echo ""
return 0
}
# 显示所有分区列表(用于删除操作)- 过滤系统关键分区
show_all_partitions_for_deletion() {
echo -e "${CYAN}${BOLD}所有分区列表(不包括系统关键分区):${RESET}"
echo ""
local index=1
declare -gA all_partition_map
all_partition_map=()
while IFS= read -r line; do
local fields=($line)
local name="${fields[0]}"
local type="${fields[1]}"
local size="${fields[2]}"
local fstype="${fields[3]}"
local mountpoint="${fields[4]}"
if [ "$type" = "part" ] && [ -b "/dev/$name" ]; then
# 过滤系统关键分区
if [ "$mountpoint" = "/" ] || [ "$mountpoint" = "/boot" ] || [ "$fstype" = "swap" ]; then
continue # 跳过根分区、引导分区和swap分区
fi
all_partition_map[$index]="/dev/$name|$fstype|$mountpoint|$size"
local mount_display=""
if [ -n "$mountpoint" ]; then
mount_display="${GREEN}已挂载: $mountpoint${RESET}"
else
mount_display="${YELLOW}未挂载${RESET}"
fi
if [ -z "$fstype" ] || [ "$fstype" = "" ]; then
fstype_display="${RED}无文件系统${RESET}"
else
fstype_display="${YELLOW}$fstype${RESET}"
fi
printf " ${GREEN}%2d${RESET}) ${BLUE}%-12s${RESET} ${CYAN}%8s${RESET} ${YELLOW}%-10s${RESET} %s\n" \
"$index" "/dev/$name" "$size" "$fstype_display" "$mount_display"
index=$((index+1))
fi
done < <(lsblk -l -n -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT | sort -V)
if [ $index -eq 1 ]; then
echo -e " ${YELLOW}没有找到可安全删除的分区${RESET}"
echo -e " ${YELLOW}(系统关键分区已自动隐藏)${RESET}"
echo ""
return 1
fi
echo ""
return 0
}
# 显示所有磁盘列表(用于删除分区表)
show_all_disks_for_deletion() {
echo -e "${CYAN}${BOLD}所有磁盘列表:${RESET}"
echo ""
local index=1
declare -gA all_disk_map
all_disk_map=()
while IFS= read -r line; do
local fields=($line)
local disk="${fields[0]}"
local type="${fields[1]}"
local size="${fields[2]}"
if [ "$type" = "disk" ] && [ -b "/dev/$disk" ]; then
all_disk_map[$index]="/dev/$disk"
# 获取分区数量
local partition_count=$(lsblk -l -n -o NAME,TYPE | grep "^${disk}[0-9]" | grep -c "part")
printf " ${GREEN}%2d${RESET}) ${BLUE}%-12s${RESET} ${CYAN}%8s${RESET} ${YELLOW}%d个分区${RESET}\n" \
"$index" "/dev/$disk" "$size" "$partition_count"
index=$((index+1))
fi
done < <(lsblk -d -n -o NAME,TYPE,SIZE | grep -vE '^loop|^sr' | sort -V)
if [ $index -eq 1 ]; then
echo -e " ${YELLOW}没有找到磁盘${RESET}"
echo ""
return 1
fi
echo ""
return 0
}
# 简单的进度显示
simple_progress() {
local seconds=$1
local message=$2
echo -ne "${BLUE}[INFO]${RESET} $message "
for ((i=0; i<seconds; i++)); do
echo -n "."
sleep 1
done
echo -e " ${GREEN}完成${RESET}"
}
# 选择分区表类型
choose_partition_table() {
echo -e "${CYAN}${BOLD}选择分区表类型:${RESET}"
echo ""
echo -e " ${GREEN}1${RESET}) GPT (推荐,支持2TB以上磁盘,最多128个分区)"
echo -e " ${GREEN}2${RESET}) MBR (兼容性好,支持最多4个主分区)"
echo ""
while true; do
read -p "请选择分区表类型 1. GPT(推荐)2. MBR(兼容性好)(默认: 1): " pt_choice
pt_choice=${pt_choice:-1}
if [[ "$pt_choice" == "1" ]]; then
echo "gpt"
return 0
elif [[ "$pt_choice" == "2" ]]; then
echo "mbr"
return 0
else
echo -e "${RED}[✗]${RESET} 无效选择,请输入 1 或 2"
fi
done
}
# 创建分区(支持多种工具和分区表)
create_partition() {
local device=$1
local partition_table=$2
echo -e "${BLUE}[INFO]${RESET} 正在为 $device 创建分区..."
# 确保分区工具可用
if [ "$PARTITION_TOOL" = "parted" ]; then
if ! install_package "parted" "parted分区工具"; then
echo -e "${RED}[✗]${RESET} 无法安装parted,尝试使用fdisk"
PARTITION_TOOL="fdisk"
fi
fi
if [ "$PARTITION_TOOL" = "fdisk" ]; then
if ! install_package "fdisk" "fdisk分区工具"; then
echo -e "${RED}[✗]${RESET} 无法安装fdisk"
return 1
fi
fi
if [ "$PARTITION_TOOL" = "parted" ]; then
# 使用parted创建分区
if [ "$partition_table" = "gpt" ]; then
parted -s "$device" mklabel gpt > /dev/null 2>&1
parted -s "$device" mkpart primary 0% 100% > /dev/null 2>&1
else
parted -s "$device" mklabel msdos > /dev/null 2>&1
parted -s "$device" mkpart primary 0% 100% > /dev/null 2>&1
fi
elif [ "$PARTITION_TOOL" = "fdisk" ]; then
# 使用fdisk创建分区
if [ "$partition_table" = "gpt" ]; then
echo -e "g\nn\n\n\n\n\nw\n" | fdisk "$device" > /dev/null 2>&1
else
echo -e "o\nn\n\n\n\n\nw\n" | fdisk "$device" > /dev/null 2>&1
fi
fi
# 刷新分区表
sleep 2
if command -v partprobe > /dev/null 2>&1; then
partprobe "$device" > /dev/null 2>&1
elif command -v udevadm > /dev/null 2>&1; then
udevadm settle > /dev/null 2>&1
fi
sleep 2
# 查找新分区
local new_partition=""
for i in {1..5}; do
if [ -b "${device}1" ]; then
new_partition="${device}1"
break
elif [ -b "${device}p1" ]; then
new_partition="${device}p1"
break
fi
sleep 1
done
if [ -n "$new_partition" ] && [ -b "$new_partition" ]; then
echo "$new_partition"
return 0
fi
return 1
}
# 扩展版格式化菜单
show_format_menu() {
local partition=$1
local has_fs=$2
FORMAT_RESULT=""
if [ "$has_fs" = "true" ]; then
echo -e "${YELLOW}[!]${RESET} 确认重新格式化该分区(数据将丢失)"
else
echo -e "${YELLOW}[!]${RESET} 未检测到文件系统,需要先格式化"
fi
echo -e "${CYAN}${BOLD}文件系统类型列表:${RESET}"
echo ""
declare -A fs_map
fs_map[1]="ext4 (推荐,兼容性好)"
fs_map[2]="xfs (高性能,适合大文件)"
fs_map[3]="ext3 (兼容旧系统)"
fs_map[4]="btrfs (高级功能,快照)"
fs_map[5]="ntfs (Windows兼容)"
fs_map[6]="fat32 (通用兼容,小文件)"
# 根据系统安装情况调整
if ! command -v mkfs.ext4 > /dev/null 2>&1; then
unset fs_map[1]
fi
if ! command -v mkfs.xfs > /dev/null 2>&1; then
unset fs_map[2]
fi
if ! command -v mkfs.ext3 > /dev/null 2>&1; then
unset fs_map[3]
fi
if ! command -v mkfs.btrfs > /dev/null 2>&1; then
unset fs_map[4]
fi
if ! command -v mkfs.ntfs > /dev/null 2>&1; then
unset fs_map[5]
fi
if ! command -v mkfs.fat > /dev/null 2>&1; then
unset fs_map[6]
fi
if [ ${#fs_map[@]} -eq 0 ]; then
echo -e "${RED}[✗]${RESET} 没有可用的文件系统工具"
return 1
fi
for i in $(echo "${!fs_map[@]}" | tr ' ' '\n' | sort -n); do
printf " ${GREEN}%2d${RESET}) ${YELLOW}%-30s${RESET}\n" "$i" "${fs_map[$i]}"
done
echo ""
while true; do
read -p "请输入文件系统编号 (默认: 1): " fs_choice
fs_choice=${fs_choice:-1}
if [[ ! "${!fs_map[@]}" =~ $fs_choice ]]; then
echo -e "${RED}[✗]${RESET} 无效选择"
continue
fi
case $fs_choice in
1)
if ! install_package "e2fsprogs" "ext4工具"; then
continue
fi
echo -e "${BLUE}[INFO]${RESET} 正在格式化为 ext4..."
mkfs.ext4 -F -m 0 "$partition" > /dev/null 2>&1
simple_progress 3 "格式化ext4文件系统"
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} 格式化完成"
FORMAT_RESULT="ext4"
else
echo -e "${RED}[✗]${RESET} 格式化失败"
fi
;;
2)
if ! install_package "xfsprogs" "xfs工具"; then
continue
fi
echo -e "${BLUE}[INFO]${RESET} 正在格式化为 xfs..."
mkfs.xfs -f "$partition" > /dev/null 2>&1
simple_progress 3 "格式化xfs文件系统"
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} 格式化完成"
FORMAT_RESULT="xfs"
else
echo -e "${RED}[✗]${RESET} 格式化失败"
fi
;;
3)
if ! install_package "e2fsprogs" "ext3工具"; then
continue
fi
echo -e "${BLUE}[INFO]${RESET} 正在格式化为 ext3..."
mkfs.ext3 -F "$partition" > /dev/null 2>&1
simple_progress 3 "格式化ext3文件系统"
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} 格式化完成"
FORMAT_RESULT="ext3"
else
echo -e "${RED}[✗]${RESET} 格式化失败"
fi
;;
4)
if ! install_package "btrfs-progs" "btrfs工具"; then
continue
fi
echo -e "${BLUE}[INFO]${RESET} 正在格式化为 btrfs..."
mkfs.btrfs -f "$partition" > /dev/null 2>&1
simple_progress 3 "格式化btrfs文件系统"
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} 格式化完成"
FORMAT_RESULT="btrfs"
else
echo -e "${RED}[✗]${RESET} 格式化失败"
fi
;;
5)
if ! install_package "ntfs-3g" "NTFS工具"; then
continue
fi
echo -e "${BLUE}[INFO]${RESET} 正在格式化为 NTFS..."
mkfs.ntfs -f -Q "$partition" > /dev/null 2>&1
simple_progress 3 "格式化NTFS文件系统"
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} 格式化完成"
FORMAT_RESULT="ntfs"
else
echo -e "${RED}[✗]${RESET} 格式化失败"
fi
;;
6)
if ! install_package "dosfstools" "FAT32工具"; then
continue
fi
echo -e "${BLUE}[INFO]${RESET} 正在格式化为 FAT32..."
mkfs.fat -F 32 -n "DATA" "$partition" > /dev/null 2>&1
simple_progress 3 "格式化FAT32文件系统"
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} 格式化完成"
FORMAT_RESULT="fat32"
else
echo -e "${RED}[✗]${RESET} 格式化失败"
fi
;;
esac
if [ -n "$FORMAT_RESULT" ]; then
return 0
fi
done
}
# 挂载分区
mount_partition() {
local partition=$1
local mount_point=$2
if [ ! -d "$mount_point" ]; then
mkdir -p "$mount_point"
echo -e "${BLUE}[INFO]${RESET} 创建挂载目录: $mount_point"
fi
echo -e "${BLUE}[INFO]${RESET} 正在挂载 $partition 到 $mount_point ..."
mount "$partition" "$mount_point" > /dev/null 2>&1
if [ $? -eq 0 ]; then
simple_progress 2 "挂载文件系统"
echo -e "${GREEN}[✓]${RESET} 挂载成功"
chmod 755 "$mount_point"
local uuid=$(blkid -s UUID -o value "$partition" 2>/dev/null)
if [ -n "$uuid" ]; then
local fs_type=$(lsblk -n -o FSTYPE "$partition" 2>/dev/null | head -1)
sed -i "\|^[^#].*$mount_point[[:space:]]|d" /etc/fstab 2>/dev/null
sed -i "\|^[^#].*$partition[[:space:]]|d" /etc/fstab 2>/dev/null
echo "UUID=$uuid $mount_point $fs_type defaults 0 0" >> /etc/fstab
echo -e "${GREEN}[✓]${RESET} 已配置开机自动挂载"
mount -a > /dev/null 2>&1
simple_progress 1 "测试fstab配置"
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} fstab配置测试通过"
else
echo -e "${YELLOW}[!]${RESET} fstab配置测试失败"
fi
fi
return 0
else
echo -e "${RED}[✗]${RESET} 挂载失败"
return 1
fi
}
# 删除分区表(清空整个磁盘)
delete_partition_table() {
local partition=$1
# 提取磁盘名(如从 /dev/sdb1 提取 sdb)
local disk=$(echo "$partition" | sed -E 's/^\/dev\/([a-zA-Z0-9]+)[0-9]+$/\1/')
local disk_path="/dev/$disk"
echo -e "${RED}[WARNING]${RESET} 即将删除 $disk_path 上的所有分区!"
echo -e "${RED}[WARNING]${RESET} 此操作将彻底清空该磁盘的分区表,所有数据将永久丢失!"
echo -e "${RED}[WARNING]${RESET} 磁盘上的所有分区都会被删除,无法恢复!"
# 显示磁盘当前分区信息
echo -e "${YELLOW}当前分区信息:${RESET}"
fdisk -l "$disk_path" 2>/dev/null | grep "^/dev/" || echo " 无分区信息"
read -p "最终确认删除 $disk_path 的所有分区和分区表?[y/N]: " delete_confirm
if [[ ! "$delete_confirm" =~ ^[Yy]$ ]]; then
echo -e "${BLUE}[INFO]${RESET} 取消删除分区表操作"
return 0
fi
# 安装parted(如果未安装)
if ! command -v parted > /dev/null 2>&1; then
echo -e "${YELLOW}[!]${RESET} 正在安装parted工具..."
if ! install_package "parted" "parted分区工具"; then
echo -e "${RED}[✗]${RESET} 无法安装parted"
return 1
fi
fi
echo -e "${BLUE}[INFO]${RESET} 正在清除 $disk_path 的分区表..."
# 方法1:使用dd清除分区表(最彻底)
echo -e "${BLUE}[INFO]${RESET} 方法1:使用dd清除分区表签名..."
dd if=/dev/zero of="$disk_path" bs=512 count=1 conv=notrunc 2>/dev/null
simple_progress 2 "清除MBR/GPT签名"
# 方法2:使用wipefs清除所有签名
echo -e "${BLUE}[INFO]${RESET} 方法2:使用wipefs清除文件系统签名..."
if command -v wipefs > /dev/null 2>&1; then
wipefs -a "$disk_path" > /dev/null 2>&1
simple_progress 2 "清除文件系统签名"
fi
# 方法3:创建新的空分区表
echo -e "${BLUE}[INFO]${RESET} 方法3:创建新的空GPT分区表..."
parted -s "$disk_path" mklabel gpt > /dev/null 2>&1
simple_progress 2 "创建新分区表"
# 刷新分区表
partprobe "$disk_path" > /dev/null 2>&1
simple_progress 1 "刷新分区表"
# 验证分区是否已删除
local remaining_parts=$(lsblk -l -n -o NAME | grep "^${disk}[0-9]" | wc -l)
if [ "$remaining_parts" -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} 分区表删除成功:$disk_path 已无分区"
return 0
else
echo -e "${RED}[✗]${RESET} 分区表删除失败,仍有残留分区"
return 1
fi
}
# 删除单个分区(不删除整个分区表)- 修复swap分区问题
delete_single_partition() {
local partition=$1
# 提取磁盘名(如从 /dev/sdb1 提取 sdb)
local disk=$(echo "$partition" | sed -E 's/^\/dev\/([a-zA-Z0-9]+)[0-9]+$/\1/')
local disk_path="/dev/$disk"
local part_num=$(echo "$partition" | grep -o '[0-9]\+$')
# 检查是否为swap分区
local is_swap=false
if command -v lsblk > /dev/null 2>&1; then
local fstype=$(lsblk -n -o FSTYPE "$partition" 2>/dev/null | head -1)
if [ "$fstype" = "swap" ]; then
is_swap=true
fi
fi
echo -e "${YELLOW}[!]${RESET} 即将删除分区 $partition"
if $is_swap; then
echo -e "${YELLOW}[!]${RESET} 这是一个swap分区"
else
echo -e "${YELLOW}[!]${RESET} 分区 $part_num 将被删除,该分区的数据将丢失"
fi
# 显示分区信息
echo -e "${CYAN}分区信息:${RESET}"
fdisk -l "$partition" 2>/dev/null | head -5 || echo " 无法获取分区信息"
read -p "确认删除分区 $partition?[y/N]: " delete_confirm
if [[ ! "$delete_confirm" =~ ^[Yy]$ ]]; then
echo -e "${BLUE}[INFO]${RESET} 取消删除分区操作"
return 0
fi
# 如果是swap分区且已启用,先关闭swap
if $is_swap; then
echo -e "${BLUE}[INFO]${RESET} 检测到swap分区,正在检查是否已启用..."
if swapon --show | grep -q "$partition"; then
echo -e "${BLUE}[INFO]${RESET} 正在关闭swap分区 $partition ..."
swapoff "$partition"
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} swap分区已关闭"
else
echo -e "${RED}[✗]${RESET} 无法关闭swap分区"
return 1
fi
fi
fi
# 使用fdisk非交互式删除分区
echo -e "${BLUE}[INFO]${RESET} 正在删除分区 $partition ..."
# 构建fdisk命令序列
local fdisk_cmds="d\n" # 删除分区
if [ -n "$part_num" ]; then
fdisk_cmds+="$part_num\n" # 分区号
fi
fdisk_cmds+="w\n" # 保存
echo -e "$fdisk_cmds" | fdisk "$disk_path" > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e "${RED}[✗]${RESET} fdisk删除失败,尝试使用parted"
# 尝试使用parted
if command -v parted > /dev/null 2>&1; then
parted -s "$disk_path" rm "$part_num" > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e "${RED}[✗]${RESET} parted删除也失败"
return 1
fi
else
echo -e "${RED}[✗]${RESET} parted未安装"
return 1
fi
fi
# 刷新分区表
partprobe "$disk_path" > /dev/null 2>&1
simple_progress 2 "刷新分区表"
# 验证分区是否已删除
if [ ! -b "$partition" ]; then
echo -e "${GREEN}[✓]${RESET} 分区删除成功:$partition 已不存在"
return 0
else
echo -e "${RED}[✗]${RESET} 分区删除失败"
return 1
fi
}
# 卸载分区
umount_partition() {
local device_mount=$1
local device=$(echo "$device_mount" | cut -d'|' -f1)
local mount_point=$(echo "$device_mount" | cut -d'|' -f2)
echo -e "${BLUE}[INFO]${RESET} 正在卸载 $device (挂载点: $mount_point)..."
if ! mount | grep -q "$device on $mount_point"; then
echo -e "${YELLOW}[!]${RESET} 该设备未挂载在 $mount_point"
return 1
fi
umount "$device" > /dev/null 2>&1
if [ $? -eq 0 ]; then
simple_progress 2 "安全卸载设备"
echo -e "${GREEN}[✓]${RESET} 卸载成功"
else
echo -e "${YELLOW}[!]${RESET} 设备被进程占用,正在显示占用进程..."
fuser -v "$mount_point" 2>/dev/null || echo " 未找到占用进程"
echo -e "${YELLOW}[!]${RESET} 尝试强制卸载..."
umount -l "$device" > /dev/null 2>&1
if [ $? -eq 0 ]; then
simple_progress 2 "强制卸载设备"
echo -e "${GREEN}[✓]${RESET} 强制卸载成功"
else
echo -e "${RED}[✗]${RESET} 卸载失败"
return 1
fi
fi
# 清理fstab中的条目
sed -i "\|^[^#].*$mount_point[[:space:]]|d" /etc/fstab 2>/dev/null
sed -i "\|^[^#].*$device[[:space:]]|d" /etc/fstab 2>/dev/null
echo -e "${GREEN}[✓]${RESET} 已清理开机自动挂载配置"
return 0
}
# 主程序
main() {
check_root
check_system_compatibility
while true; do
show_system_info
show_disk_info
echo -e "${CYAN}${BOLD}请选择操作类型:${RESET}"
echo ""
echo -e " ${GREEN}1${RESET}) 挂载磁盘/分区"
echo -e " ${GREEN}2${RESET}) 卸载磁盘/分区"
echo -e " ${GREEN}3${RESET}) 删除分区/分区表"
echo -e " ${GREEN}4${RESET}) 显示系统信息"
echo -e " ${GREEN}q${RESET}) 退出脚本"
echo ""
read -p "请输入选择 [1/2/3/4/q]: " main_choice
echo ""
case $main_choice in
1)
# 挂载磁盘/分区
if ! show_available_mount_devices; then
echo -e "${YELLOW}按回车键返回主菜单...${RESET}"
read -p ""
clear
continue
fi
echo -e "${CYAN}请输入设备编号 (或输入q返回):${RESET}"
read -p "> " choice
if [ "$choice" = "q" ]; then
clear
continue
fi
local selected_device="${device_map[$choice]}"
if [ -z "$selected_device" ]; then
echo -e "${RED}[✗]${RESET} 无效的选择"
sleep 2
clear
continue
fi
echo ""
echo -e "${CYAN}══════════════════════════════════════════${RESET}"
echo -e "${CYAN}已选择设备:${RESET} ${GREEN}$selected_device${RESET}"
echo -e "${CYAN}══════════════════════════════════════════${RESET}"
echo ""
local partition=""
local fs_type=""
if [[ "$selected_device" =~ [0-9]$ ]] || [[ "$selected_device" =~ p[0-9]+$ ]]; then
# 选择的是分区
partition="$selected_device"
fs_type=$(lsblk -n -o FSTYPE "$partition" 2>/dev/null | head -1 | xargs)
if [ -n "$fs_type" ] && [ "$fs_type" != "" ]; then
echo -e "${CYAN}检测到文件系统:${RESET} ${YELLOW}$fs_type${RESET}"
read -p "是否重新格式化?[y/N]: " reformat
if [[ "$reformat" =~ ^[Yy]$ ]]; then
show_format_menu "$partition" "true"
fs_type=$FORMAT_RESULT
if [ -z "$fs_type" ]; then
echo -e "${YELLOW}按回车返回...${RESET}"
read
clear
continue
fi
fi
else
show_format_menu "$partition" "false"
fs_type=$FORMAT_RESULT
if [ -z "$fs_type" ]; then
echo -e "${YELLOW}按回车返回...${RESET}"
read
clear
continue
fi
fi
else
# 选择的是未分区的磁盘
echo -e "${CYAN}该设备是磁盘,需要先创建分区${RESET}"
read -p "是否创建分区?[Y/n]: " create_part
if [[ "$create_part" =~ ^[Nn]$ ]]; then
echo -e "${YELLOW}操作取消${RESET}"
sleep 1
clear
continue
fi
# 选择分区表类型
local partition_table=$(choose_partition_table)
if [ -z "$partition_table" ]; then
echo -e "${YELLOW}按回车返回...${RESET}"
read
clear
continue
fi
echo -e "${BLUE}══════════════════════════════════════════${RESET}"
echo -e "${BLUE}开始创建分区${RESET}"
echo -e "${BLUE}══════════════════════════════════════════${RESET}"
echo ""
partition=$(create_partition "$selected_device" "$partition_table")
if [ $? -ne 0 ] || [ -z "$partition" ]; then
echo -e "${RED}分区创建失败,按回车返回...${RESET}"
read
clear
continue
fi
echo -e "${GREEN}[✓]${RESET} 分区创建完成: $partition"
echo ""
# 重要:创建分区表后,提示用户重新运行脚本
echo -e "${YELLOW}[!]${RESET} 分区表已创建,需要重新扫描设备..."
echo -e "${YELLOW}[!]${RESET} 请按回车键返回主菜单,然后重新选择'挂载磁盘/分区'选项"
echo ""
read -p "按回车键继续..."
clear
continue
fi
if [ -z "$fs_type" ]; then
echo -e "${RED}[✗]${RESET} 无法确定文件系统类型"
echo -e "${YELLOW}按回车返回...${RESET}"
read
clear
continue
fi
# 输入挂载点
echo -e "${BLUE}══════════════════════════════════════════${RESET}"
echo -e "${BLUE}设置挂载点${RESET}"
echo -e "${BLUE}══════════════════════════════════════════${RESET}"
echo ""
echo -e "${CYAN}请输入挂载点路径${RESET}"
echo -e "示例: ${YELLOW}/data${RESET}, ${YELLOW}/www${RESET}, ${YELLOW}/mnt/disk${RESET}"
while true; do
read -p "> " mount_point
if [ -z "$mount_point" ]; then
echo -e "${RED}[✗]${RESET} 挂载点不能为空"
continue
fi
if [[ ! "$mount_point" =~ ^/ ]]; then
echo -e "${RED}[✗]${RESET} 挂载点必须以 / 开头"
continue
fi
if mount | grep -q " on $mount_point "; then
local mounted_dev=$(mount | grep " on $mount_point " | awk '{print $1}')
if [ "$mounted_dev" != "$partition" ]; then
echo -e "${RED}[✗]${RESET} 该目录已被 $mounted_dev 挂载"
continue
fi
fi
break
done
# 执行挂载
echo ""
echo -e "${BLUE}══════════════════════════════════════════${RESET}"
echo -e "${BLUE}开始挂载${RESET}"
echo -e "${BLUE}══════════════════════════════════════════${RESET}"
echo ""
if mount_partition "$partition" "$mount_point"; then
echo ""
echo -e "${PURPLE}══════════════════════════════════════════${RESET}"
echo -e "${GREEN} 挂载完成! ${RESET}"
echo -e "${PURPLE}══════════════════════════════════════════${RESET}"
echo ""
echo -e "${CYAN}挂载信息:${RESET}"
echo -e " 设备: ${GREEN}$partition${RESET}"
echo -e " 挂载点: ${BLUE}$mount_point${RESET}"
echo -e " 文件系统: ${YELLOW}$fs_type${RESET}"
echo -e " 容量: $(lsblk -n -o SIZE "$partition" 2>/dev/null | head -1)"
echo ""
echo -e "${CYAN}磁盘空间:${RESET}"
df -h "$mount_point" 2>/dev/null | tail -1 | awk '{print " 使用: " $3 " / " $2 " (" $5 ")"}'
echo ""
fi
echo ""
read -p "按回车键返回主菜单..."
clear
;;
2)
# 卸载磁盘/分区
if ! show_mounted_devices; then
echo -e "${YELLOW}按回车键返回主菜单...${RESET}"
read -p ""
clear
continue
fi
echo -e "${CYAN}请输入设备编号 (或输入q返回):${RESET}"
read -p "> " choice
if [ "$choice" = "q" ]; then
clear
continue
fi
local selected_mounted_device="${mounted_device_map[$choice]}"
if [ -z "$selected_mounted_device" ]; then
echo -e "${RED}[✗]${RESET} 无效的选择"
sleep 2
clear
continue
fi
echo ""
echo -e "${CYAN}══════════════════════════════════════════${RESET}"
echo -e "${CYAN}确认卸载:${RESET} ${RED}$selected_mounted_device${RESET}"
echo -e "${CYAN}══════════════════════════════════════════${RESET}"
echo ""
read -p "确认卸载?[y/N]: " confirm_umount
if [[ ! "$confirm_umount" =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}操作取消${RESET}"
sleep 1
clear
continue
fi
if umount_partition "$selected_mounted_device"; then
echo ""
echo -e "${PURPLE}══════════════════════════════════════════${RESET}"
echo -e "${GREEN} 卸载完成! ${RESET}"
echo -e "${PURPLE}══════════════════════════════════════════${RESET}"
echo ""
fi
echo ""
read -p "按回车键返回主菜单..."
clear
;;
3)
# 删除分区/分区表
echo -e "${CYAN}${BOLD}删除操作:${RESET}"
echo ""
echo -e " 1) 删除单个分区"
echo -e " 2) 删除整个磁盘的分区表"
echo -e " q) 返回主菜单"
echo ""
read -p "请选择删除类型 [1/2/q]: " delete_type
case $delete_type in
1)
# 删除单个分区
if ! show_all_partitions_for_deletion; then
echo -e "${YELLOW}按回车键返回...${RESET}"
read -p ""
clear
continue
fi
echo -e "${CYAN}请输入分区编号 (或输入q返回):${RESET}"
read -p "> " choice
if [ "$choice" = "q" ]; then
clear
continue
fi
local selected_partition_info="${all_partition_map[$choice]}"
if [ -z "$selected_partition_info" ]; then
echo -e "${RED}[✗]${RESET} 无效的选择"
sleep 2
clear
continue
fi
local partition=$(echo "$selected_partition_info" | cut -d'|' -f1)
local current_fs=$(echo "$selected_partition_info" | cut -d'|' -f2)
local current_mount=$(echo "$selected_partition_info" | cut -d'|' -f3)
local partition_size=$(echo "$selected_partition_info" | cut -d'|' -f4)
echo ""
echo -e "${CYAN}══════════════════════════════════════════${RESET}"
echo -e "${CYAN}确认删除分区:${RESET} ${RED}$partition${RESET}"
echo -e " ${WHITE}文件系统:${RESET} ${YELLOW}${current_fs:-无}${RESET}"
echo -e " ${WHITE}挂载状态:${RESET} ${YELLOW}${current_mount:-未挂载}${RESET}"
echo -e " ${WHITE}分区大小:${RESET} ${CYAN}$partition_size${RESET}"
echo -e "${CYAN}══════════════════════════════════════════${RESET}"
echo ""
if [ -n "$current_mount" ]; then
# 检查是否为swap分区
if [ "$current_fs" = "swap" ] || [ "$current_mount" = "[SWAP]" ]; then
echo -e "${RED}[!]${RESET} 警告:这是一个swap分区"
read -p "是否先关闭swap再删除?[Y/n]: " swapoff_first
if [[ ! "$swapoff_first" =~ ^[Nn]$ ]]; then
echo -e "${BLUE}[INFO]${RESET} 正在关闭swap分区 $partition ..."
swapoff "$partition" 2>/dev/null
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} swap分区已关闭"
else
echo -e "${YELLOW}[!]${RESET} 关闭swap分区失败,继续尝试删除..."
fi
fi
else
echo -e "${RED}[!]${RESET} 警告:该分区当前已挂载在 $current_mount"
read -p "是否先卸载再删除?[Y/n]: " unmount_first
if [[ ! "$unmount_first" =~ ^[Nn]$ ]]; then
echo -e "${BLUE}[INFO]${RESET} 正在卸载 $partition ..."
umount "$partition" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "${GREEN}[✓]${RESET} 卸载成功"
else
echo -e "${YELLOW}[!]${RESET} 卸载失败,尝试强制卸载..."
umount -l "$partition" > /dev/null 2>&1
fi
fi
fi
fi
# 执行删除
delete_single_partition "$partition"
# 删除分区后提示用户
echo -e "${YELLOW}[!]${RESET} 分区已删除,请按回车键返回主菜单..."
read -p ""
clear
continue
;;
2)
# 删除整个磁盘的分区表
if ! show_all_disks_for_deletion; then
echo -e "${YELLOW}按回车键返回...${RESET}"
read -p ""
clear
continue
fi
echo -e "${CYAN}请输入磁盘编号 (或输入q返回):${RESET}"
read -p "> " choice
if [ "$choice" = "q" ]; then
clear
continue
fi
local selected_disk="${all_disk_map[$choice]}"
if [ -z "$selected_disk" ]; then
echo -e "${RED}[✗]${RESET} 无效的选择"
sleep 2
clear
continue
fi
echo ""
echo -e "${CYAN}══════════════════════════════════════════${RESET}"
echo -e "${CYAN}确认删除磁盘分区表:${RESET} ${RED}$selected_disk${RESET}"
echo -e "${CYAN}══════════════════════════════════════════${RESET}"
echo ""
# 执行删除
delete_partition_table "$selected_disk"
# 删除分区表后提示用户
echo -e "${YELLOW}[!]${RESET} 分区表已删除,请按回车键返回主菜单..."
read -p ""
clear
continue
;;
q)
clear
continue
;;
*)
echo -e "${RED}[✗]${RESET} 无效选择"
sleep 2
;;
esac
echo ""
read -p "按回车键返回主菜单..."
clear
;;
4)
# 显示系统信息
clear
echo -e "${CYAN}${BOLD}详细系统信息:${RESET}"
echo ""
echo -e "${WHITE}操作系统:${RESET} $SYS_INFO"
echo -e "${WHITE}内核版本:${RESET} $(uname -r)"
echo -e "${WHITE}主机名称:${RESET} $(hostname)"
echo -e "${WHITE}系统架构:${RESET} $(uname -m)"
echo -e "${WHITE}运行环境:${RESET} $([ "$CONTAINER_ENV" = true ] && echo "容器" || echo "物理机/虚拟机")"
echo -e "${WHITE}包管理器:${RESET} $PKG_MANAGER"
echo -e "${WHITE}分区工具:${RESET} $PARTITION_TOOL"
echo -e "${WHITE}GPT支持:${RESET} $([ "$GPT_SUPPORT" = true ] && echo "是" || echo "否")"
echo -e "${WHITE}磁盘数量:${RESET} $(lsblk -d -n -o NAME | grep -vE '^loop|^sr' | wc -l)"
echo ""
read -p "按回车键返回主菜单..."
clear
;;
q|Q)
echo ""
echo -e "${GREEN}══════════════════════════════════════════${RESET}"
echo -e "${GREEN} 感谢使用磁盘挂载助手! ${RESET}"
echo -e "${GREEN}══════════════════════════════════════════${RESET}"
echo ""
exit 0
;;
*)
echo -e "${RED}[✗]${RESET} 无效选择"
sleep 2
clear
;;
esac
done
}
# 捕获中断
trap 'echo -e "\n${RED}操作被中断${RESET}"; exit 1' INT
# 运行
main "$@"
功能详解
一、挂载新磁盘(选项1)
场景:添加新硬盘后需要分区、格式化并挂载
步骤:
- 选择菜单选项
1 - 从列表中选择要操作的设备
- 如果是未分区的磁盘,脚本会自动引导创建分区
- 如果已有分区但未格式化,可选择文件系统类型
- 选择分区表类型(GPT推荐用于2TB以上磁盘)
- 选择文件系统类型:
- ext4:推荐,兼容性好
- xfs:高性能,适合大文件
- btrfs:支持快照等高级功能
- NTFS:Windows兼容
- FAT32:通用兼容
- 指定挂载点目录(如:
/data、/www、/mnt/disk1)
脚本自动完成:
- 创建分区表(GPT/MBR)
- 创建分区
- 格式化指定文件系统
- 创建挂载目录
- 挂载分区
- 配置开机自动挂载(/etc/fstab)
- 验证配置有效性
二、卸载磁盘(选项2)
场景:安全移除已挂载的磁盘
步骤:
- 选择菜单选项
2 - 从已挂载设备列表中选择要卸载的设备
- 确认卸载操作
卸载后可选操作:
- 仅卸载,保留数据
- 重新格式化分区
- 删除该分区(保留分区表)
- 删除整个磁盘的分区表(清空所有分区)
三、删除分区/分区表(选项3)
场景:清理不需要的分区或重新规划磁盘
安全特性:
- 自动隐藏系统关键分区(根分区、引导分区、swap)
- 多重确认防止误操作
- 支持swap分区安全删除
操作类型:
- 删除单个分区:仅删除指定分区,不影响其他分区
- 删除分区表:清空整个磁盘的所有分区(数据将永久丢失)
高级特性
1. 智能包管理
脚本自动检测系统包管理器并安装所需工具:
- Debian/Ubuntu:使用apt
- CentOS/RHEL:使用yum
- Arch/Manjaro:使用pacman
- openSUSE:使用zypper
2. 安全保护机制
- Root权限检查
- 系统关键分区保护
- 操作前确认提示
- 进程占用检查
3. 容器环境适配
自动检测Docker/Kubernetes容器环境,调整操作策略
4. 进度可视化
所有耗时操作都显示美观的进度条:
[INFO] 格式化ext4文件系统 [██████████████████████████████] 100% ✓
使用示例
示例1:挂载新数据盘
# 运行脚本
bash <(curl -s http://disk.6wd.cn/mount-disk.sh)
# 操作流程:
# 1. 选择选项1(挂载)
# 2. 选择新磁盘(如/dev/sdb)
# 3. 选择GPT分区表
# 4. 选择ext4文件系统
# 5. 输入挂载点:/data
# 6. 脚本自动完成所有配置
示例2:扩展磁盘空间
# 当需要重新分区时:
# 1. 先选择选项2卸载磁盘
# 2. 选择选项3删除旧分区
# 3. 重新选择选项1创建更大分区
# 4. 挂载到原目录,数据会保留(如果未格式化)
故障排除
常见问题:
-
权限不足
请使用:sudo bash mount.sh -
设备被占用
[INFO] 设备被进程占用,正在显示占用进程... fuser -v 显示占用进程详情 -
包安装失败
脚本会尝试多种安装方式,如失败请手动安装: # Debian/Ubuntu sudo apt update && sudo apt install parted e2fsprogs # CentOS/RHEL sudo yum install parted e2fsprogs
注意事项
-
数据安全
- 操作前请确认已备份重要数据
- 格式化、删除分区操作不可逆
- 建议在非生产环境先测试
-
系统要求
- Linux内核2.6以上版本
- Root权限
- 基本的命令行工具(lsblk、blkid等)
-
推荐实践
- 生产环境先在测试机验证
- 重要操作前手动备份fstab
- 使用LVM管理复杂存储需求
更新日志
- v6.1:增强容器支持,优化进度显示
- v6.0:跨平台重构,支持更多发行版
- v5.x:添加分区删除功能,改进UI
结语
Linux磁盘挂载助手通过自动化复杂操作,让磁盘管理变得简单直观。无论是单次部署还是批量管理,这个脚本都能显著提高工作效率。开源免费,持续更新,欢迎反馈和改进建议!
立即体验:
bash <(curl -s http://disk.6wd.cn/mount-disk.sh)
作者:[昴]
许可证:开源免费使用
支持:GitHub Issues / 邮箱联系
版本:v6.1 跨平台版
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,完整转载请注明来自 枫の屋
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果

