本文目录导读:

在Shell脚本中清理未挂载的卷需要谨慎操作,避免误删数据,以下是几种常见文件系统下的清理方法:
Linux 系统清理方法
查看并清理未挂载的卷
#!/bin/bash
# 查看所有磁盘和分区
echo "=== 所有磁盘分区 ==="
lsblk
# 查找未挂载的分区(没有 MOUNTPOINT 的)
echo "=== 未挂载的分区 ==="
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep -v "mounted\|/"
# 或者使用 blkid 查看
echo "=== 使用 blkid 查看 ==="
blkid
# 清理未挂载的卷(危险操作,需要确认)
UMOUNTED=$(lsblk -o NAME,MOUNTPOINT,TYPE | grep -E "disk|part" | awk '{if ($2 == "" && $3 != "lvm" && $3 != "mpath") print $1}')
echo "找到以下未挂载的分区:"
echo "$UMOUNTED"
# 可以选择性清理
for disk in $UMOUNTED; do
read -p "是否清理 /dev/$disk? (y/n): " confirm
if [ "$confirm" = "y" ]; then
echo "正在清理 /dev/$disk..."
# 使用 dd 命令清空(危险操作)
# dd if=/dev/zero of=/dev/$disk bs=1M count=100 2>/dev/null
# 或者只清除分区表
# wipefs -a /dev/$disk
echo "已完成"
fi
done
使用 findmnt 更精确地查找
#!/bin/bash
# 获取所有未挂载的分区
get_unmounted() {
local mounted
mounted=$(findmnt -D -o SOURCE,TARGET | grep -E "^/" | awk '{print $1}' | sort -u)
local all_devices
all_devices=$(lsblk -o NAME,TYPE | grep -E "disk|part" | awk '{print "/dev/"$1}')
for device in $all_devices; do
if ! echo "$mounted" | grep -q "$device"; then
echo "$device"
fi
done
}
# 清理未挂载的LVM卷
clean_lvm_unmounted() {
echo "=== LVM 未挂载卷 ==="
lvs -o lv_name,lv_path,attr --noheadings 2>/dev/null | while read line; do
lv_path=$(echo $line | awk '{print $2}')
lv_attr=$(echo $line | awk '{print $3}')
# 如果属性不是 'a'(active),说明未挂载
if [[ $lv_attr != a* ]]; then
echo "发现未挂载的LVM卷: $lv_path"
lvchange -ay "$lv_path" 2>/dev/null || true
fi
done
}
# 执行清理
clean_unmounted_volumes() {
echo "警告:此操作将清理(擦除)未挂载的卷"
echo "执行前请确保:"
echo "1. 已备份重要数据"
echo "2. 已确认这些卷确实不需要"
echo ""
read -p "是否继续? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
echo "操作已取消"
exit 1
fi
unmounted_devices=$(get_unmounted)
if [ -z "$unmounted_devices" ]; then
echo "没有找到未挂载的设备"
exit 0
fi
echo "以下设备将被清理:"
echo "$unmounted_devices"
for device in $unmounted_devices; do
echo "正在清理 $device ..."
# 使用安全方式清理(只清除分区表标签)
sudo wipefs -a "$device" 2>/dev/null || echo "跳过 $device (可能正在使用)"
done
echo "清理完成"
}
# 主函数
main() {
echo "=== 系统卷检查工具 ==="
echo ""
clean_lvm_unmounted
echo ""
clean_unmounted_volumes
}
main
macOS 系统清理方法
#!/bin/bash
# macOS 下清理未挂载的卷
clean_macos_unmounted() {
# 查看所有磁盘
echo "=== 所有磁盘 ==="
diskutil list
# 查找未挂载的卷
echo "=== 未挂载的卷 ==="
diskutil list external internal | grep -E "^/dev"
# 获取未挂载的卷列表
unmounted_volumes=$(diskutil list | grep -E "^/dev" | grep -v "mounted" | awk '{print $1}')
for volume in $unmounted_volumes; do
echo "发现未挂载的卷: $volume"
# 安全方式:弹出卷
diskutil eject "$volume" 2>/dev/null && echo "已弹出 $volume"
# 或者完全擦除(危险)
# diskutil eraseDisk JHFS+ "Clean" /dev/diskX
done
}
Docker 卷清理(特殊场景)
#!/bin/bash
# 清理 Docker 未使用的卷
clean_docker_volumes() {
echo "=== Docker 卷状态 ==="
# 查看所有卷
echo "所有Docker卷:"
docker volume ls
# 清理未被使用的卷
echo "清理未使用的Docker卷..."
docker volume prune -f
# 查看清理后的情况
echo "清理后剩余的卷:"
docker volume ls
}
# 清理所有未使用的Docker资源
clean_all_docker() {
echo "清理所有未使用的Docker资源..."
docker system prune -a --volumes -f
}
安全清理脚本(推荐)
#!/bin/bash
# 安全清理未挂载卷的脚本
set -euo pipefail
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 错误处理
error_exit() {
log "错误: $1"
exit 1
}
# 获取未挂载的设备
get_unmounted_devices() {
local mounted_devices=$(findmnt -D -o SOURCE | grep "^/" | sort -u)
local all_block_devices=$(lsblk -o NAME,TYPE,MOUNTPOINT | grep -E "disk|part" | grep -v "loop")
echo "$all_block_devices" | while read line; do
local device="/dev/$(echo $line | awk '{print $1}')"
local mountpoint=$(echo $line | awk '{print $3}')
if [ -z "$mountpoint" ] && [ -b "$device" ]; then
# 检查是否被挂载到其他地方
if ! echo "$mounted_devices" | grep -q "$device"; then
echo "$device"
fi
fi
done
}
# 主清理函数
main_clean() {
log "开始检查未挂载的卷..."
local devices=$(get_unmounted_devices)
if [ -z "$devices" ]; then
log "没有找到未挂载的设备"
exit 0
fi
log "发现以下未挂载的设备:"
echo "$devices"
# 创建备份列表
local backup_file="/tmp/unmounted_devices_$(date +%Y%m%d_%H%M%S).txt"
echo "$devices" > "$backup_file"
log "设备列表已保存到: $backup_file"
read -p "是否继续清理? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
log "操作已取消"
exit 0
fi
# 逐设备清理
while read device; do
if [ -b "$device" ]; then
log "正在处理 $device ..."
# 获取设备信息
local device_info=$(blkid "$device" 2>/dev/null || true)
if [ -n "$device_info" ]; then
log "设备信息: $device_info"
fi
# 建议操作,默认只做标签清理
read -p "对 $device 执行完整清理(1)还是仅清理标签(2)? (1/2): " action
case $action in
1)
log "执行完整清理: $device"
# 使用 dd 清理(危险)
# dd if=/dev/zero of="$device" bs=1M count=100 2>/dev/null
log "警告: 完整清理操作已注释,请手动执行"
;;
2)
log "清除标签信息: $device"
wipefs -a "$device" 2>/dev/null && log "标签清除成功" || log "标签清除失败"
;;
*)
log "跳过 $device"
;;
esac
fi
done <<< "$devices"
log "清理完成"
}
# 执行主函数
main_clean
重要注意事项
- 数据安全:清理前务必备份重要数据
- 权限要求:操作磁盘需要 root 权限
- 确认操作:建议先用
lsblk和blkid查看确认 - 测试环境:先在测试环境中验证脚本
这些脚本提供了不同安全级别的清理选项,建议从最安全的选项开始。