本文目录导读:

针对不同操作系统和需求,有以下几种脚本方案可以实现磁盘碎片监测:
Windows系统(PowerShell)
基础碎片检测脚本
# 磁盘碎片检测脚本
$drives = Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3"
foreach ($drive in $drives) {
$driveLetter = $drive.DeviceID
Write-Host "检查磁盘 $driveLetter ..." -ForegroundColor Yellow
# 使用系统内置的碎片分析
$analysis = Defrag.exe $driveLetter /A /U /V
# 解析结果
if ($analysis -match "无需对该卷进行碎片整理") {
Write-Host "$driveLetter - 无需整理" -ForegroundColor Green
} elseif ($analysis -match "建议对该卷进行碎片整理") {
Write-Host "$driveLetter - 需要整理!" -ForegroundColor Red
# 获取碎片率
if ($analysis -match "碎片率[=:]?\s*(\d+)%") {
$fragPercent = $Matches[1]
Write-Host "碎片率: $fragPercent%" -ForegroundColor Yellow
}
}
}
高级监测脚本(含报告生成)
# 高级碎片监测脚本
param(
[string]$ReportPath = "C:\frag_report_$(Get-Date -Format 'yyyyMMdd').csv",
[int]$WarningThreshold = 10, # 警告阈值(%)
[int]$CriticalThreshold = 20 # 严重阈值(%)
)
$results = @()
# 获取所有NTFS分区
$drives = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3 AND FileSystem='NTFS'"
foreach ($drive in $drives) {
$driveLetter = $drive.DeviceID
# 执行碎片分析
$output = defrag $driveLetter /A /O 2>&1
# 解析输出
$fragPercent = 0
$status = "Unknown"
if ($output -match "(\d+)%" ) {
$fragPercent = [int]$Matches[1]
if ($fragPercent -ge $CriticalThreshold) {
$status = "CRITICAL"
} elseif ($fragPercent -ge $WarningThreshold) {
$status = "WARNING"
} else {
$status = "OK"
}
}
# 构建结果对象
$result = [PSCustomObject]@{
Drive = $driveLetter
FragPercent = $fragPercent
Status = $status
Timestamp = Get-Date
TotalSizeGB = [math]::Round($drive.Size / 1GB, 2)
FreeSpaceGB = [math]::Round($drive.FreeSpace / 1GB, 2)
}
$results += $result
}
# 输出结果
$results | Format-Table -AutoSize
# 导出报告
$results | Export-Csv -Path $ReportPath -NoTypeInformation
Write-Host "`n=== 碎片状态摘要 ===" -ForegroundColor Cyan
Write-Host "Total drives checked: $($results.Count)"
Write-Host "Critical ($CriticalThreshold%+): $(($results | Where-Object Status -eq 'CRITICAL').Count)"
Write-Host "Warning ($WarningThreshold%-$CriticalThreshold%): $(($results | Where-Object Status -eq 'WARNING').Count)"
Write-Host "OK (below $WarningThreshold%): $(($results | Where-Object Status -eq 'OK').Count)"
Write-Host "Report saved to: $ReportPath"
Linux系统(Bash脚本)
使用e2fsprogs工具(支持ext4)
#!/bin/bash
# 磁盘碎片检测脚本 (Linux)
LOG_FILE="/var/log/frag_check_$(date +%Y%m%d).log"
THRESHOLD=10 # 碎片率告警阈值(%)
CHECK_DIRS=("/home" "/var" "/data") # 需要检查的目录
echo "=== 磁盘碎片检查报告 ===" | tee -a $LOG_FILE
echo "时间: $(date)" | tee -a $LOG_FILE
echo "------------------------" | tee -a $LOG_FILE
check_fragmentation() {
local mount_point=$1
local device=$(df --output=source "$mount_point" | tail -1)
if [ -z "$device" ]; then
echo "无法获取 $mount_point 的设备信息" | tee -a $LOG_FILE
return
fi
echo "检查 $mount_point ($device)..." | tee -a $LOG_FILE
# 检查是否需要root权限
if [ $(id -u) -ne 0 ]; then
echo "警告: 需要root权限获取详细碎片信息" | tee -a $LOG_FILE
fi
# 使用e2fsprogs检查碎片情况
if command -v e2fsck &> /dev/null; then
# 检查inode碎片率(只读模式)
output=$(e2fsck -fn "$device" 2>&1 | grep -i "fragmentation")
if [ ! -z "$output" ]; then
echo "碎片信息: $output" | tee -a $LOG_FILE
fi
else
echo "提示: 安装e2fsprogs获取详细碎片信息" | tee -a $LOG_FILE
fi
# 使用filefrag检查大文件碎片
if command -v filefrag &> /dev/null; then
echo "检查大文件碎片..." | tee -a $LOG_FILE
find "$mount_point" -type f -size +100M 2>/dev/null | head -10 | while read file; do
extents=$(filefrag -v "$file" 2>/dev/null | grep -c "extent")
if [ $extents -gt 100 ]; then
echo " 高碎片文件: $file (extents: $extents)" | tee -a $LOG_FILE
fi
done
fi
# 使用FIBMAP/FIEMAP检查(需要root)
if [ $(id -u) -eq 0 ] && [ -f /usr/include/linux/fiemap.h ]; then
# 这里可以集成更高级的检查工具
echo "高级碎片检查功能可用" | tee -a $LOG_FILE
fi
}
# 执行检查
for dir in "${CHECK_DIRS[@]}"; do
if [ -d "$dir" ]; then
check_fragmentation "$dir"
else
echo "目录 $dir 不存在,跳过" | tee -a $LOG_FILE
fi
done
echo "------------------------" | tee -a $LOG_FILE
echo "检查完成" | tee -a $LOG_FILE
使用inotify监测实时碎片生成
#!/bin/bash
# 实时碎片监测脚本
MONITOR_DIR="/data"
LOG_FILE="/var/log/frag_monitor.log"
echo "开始监控目录: $MONITOR_DIR" | tee -a $LOG_FILE
# 监控文件创建和修改
inotifywait -m -r -e create,modify --format '%w%f' "$MONITOR_DIR" 2>/dev/null | while read file
do
if [ -f "$file" ]; then
size=$(stat -c%s "$file" 2>/dev/null)
# 只监控大文件(>50MB)
if [ "$size" -gt 52428800 ]; then
echo "[$(date)] 大文件变动: $file (${size} bytes)" | tee -a $LOG_FILE
# 检查碎片情况
if command -v filefrag &> /dev/null; then
extents=$(filefrag -v "$file" 2>/dev/null | grep -c "extent")
if [ $extents -gt 50 ]; then
echo " 警告: 碎片数 $extents" | tee -a $LOG_FILE
fi
fi
fi
fi
done
跨平台方案(Python)
#!/usr/bin/env python3
"""
跨平台磁盘碎片检测脚本
支持: Windows, Linux, macOS
"""
import os
import sys
import subprocess
import json
from datetime import datetime
class FragmentationChecker:
def __init__(self, warning_threshold=10, critical_threshold=20):
self.warning = warning_threshold
self.critical = critical_threshold
self.results = []
def check_windows(self):
"""Windows碎片检查"""
try:
# 使用defrag命令(需要管理员权限)
result = subprocess.run(
['defrag', '/A', '/O'],
capture_output=True, text=True, shell=True
)
# 解析输出
for line in result.stdout.split('\n'):
if '%' in line and ('卷' in line or 'Volume' in line):
print(f"[Win] {line.strip()}")
except Exception as e:
print(f"Windows检查失败: {e}")
def check_linux(self, mount_points=['/home', '/var']):
"""Linux碎片检查"""
for mount in mount_points:
try:
# 获取分区设备
result = subprocess.run(
['df', '--output=source', mount],
capture_output=True, text=True
)
lines = result.stdout.strip().split('\n')
if len(lines) > 1:
device = lines[-1]
# 使用e2fsck(需要root)
if os.geteuid() == 0:
result = subprocess.run(
['e2fsck', '-fn', device],
capture_output=True, text=True
)
print(f"[Linux] {mount} ({device}): {result.stdout[:200]}")
except Exception as e:
print(f"Linux检查失败 ({mount}): {e}")
def check_macos(self):
"""macOS碎片检查(APFS文件系统通常不需要)"""
try:
result = subprocess.run(
['diskutil', 'apfs', 'list'],
capture_output=True, text=True
)
print(f"[macOS] APFS状态: {result.stdout[:200]}")
except Exception as e:
print(f"macOS检查失败: {e}")
def run(self):
"""运行检测"""
print(f"=== 碎片检测开始 ({datetime.now()}) ===")
if sys.platform.startswith('win'):
self.check_windows()
elif sys.platform.startswith('linux'):
self.check_linux()
elif sys.platform.startswith('darwin'):
self.check_macos()
else:
print(f"不支持的操作系统: {sys.platform}")
print(f"=== 检测完成 ===")
# 使用示例
if __name__ == "__main__":
checker = FragmentationChecker(warning_threshold=10, critical_threshold=20)
checker.run()
定时监测任务设置
Windows任务计划程序
# 创建定时任务(每天凌晨2点运行)
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-File C:\scripts\frag_check.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00AM"
Register-ScheduledTask -TaskName "DiskFragmentationCheck" `
-Action $action -Trigger $trigger -RunLevel Highest
Linux crontab
# 编辑crontab crontab -e # 添加定时任务(每天凌晨3点执行) 0 3 * * * /usr/local/bin/frag_check.sh >> /var/log/frag_daily.log 2>&1
注意事项
- 权限要求:Windows需要管理员权限,Linux需要root权限
- SSD优化:SSD不需要传统碎片整理,Windows会自动处理
- 性能影响:碎片检查可能消耗I/O资源,建议在低负载时段执行
- 文件系统差异:
- Windows NTFS:使用自带defrag命令
- Linux ext4/XFS:碎片管理机制不同
- macOS APFS:自动优化,通常不需要手动处理
建议根据实际需求选择合适的脚本方案,并设置合适的时间进行定期检查。