如何用脚本监测磁盘碎片

wen 实用脚本 2

本文目录导读:

如何用脚本监测磁盘碎片

  1. Windows系统(PowerShell)
  2. Linux系统(Bash脚本)
  3. 跨平台方案(Python)
  4. 定时监测任务设置
  5. 注意事项

针对不同操作系统和需求,有以下几种脚本方案可以实现磁盘碎片监测:

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

注意事项

  1. 权限要求:Windows需要管理员权限,Linux需要root权限
  2. SSD优化:SSD不需要传统碎片整理,Windows会自动处理
  3. 性能影响:碎片检查可能消耗I/O资源,建议在低负载时段执行
  4. 文件系统差异
    • Windows NTFS:使用自带defrag命令
    • Linux ext4/XFS:碎片管理机制不同
    • macOS APFS:自动优化,通常不需要手动处理

建议根据实际需求选择合适的脚本方案,并设置合适的时间进行定期检查。

抱歉,评论功能暂时关闭!