本文目录导读:

- 方案一:Linux / Unix 环境(Shell 脚本 + Crontab)
- 方案二:Windows 环境(PowerShell + 任务计划程序)
- 方案三:内存/临时文件清理(应对高并发写爆磁盘)
- 方案四:复杂策略(使用
logrotate工具) - 关键注意事项(安全红线)
- 选择最适合你的组合
针对“自动化脚本清理上报文件”的需求,通常需要解决两个核心问题:清理时机(何时删)和清理策略(删哪些、怎么删)。
以下是几种常见的自动化清理脚本方案,覆盖不同操作系统和场景:
Linux / Unix 环境(Shell 脚本 + Crontab)
最经典、资源占用最小的方案,适用于服务器或 Linux 开发机。
核心命令:find + rm
#!/bin/bash # 文件名: clean_upload.sh # 定义要清理的目录 UPLOAD_DIR="/data/upload" # 定义保留天数(保留最近7天的文件) RETENTION_DAYS=7 # 日志文件(可选) LOG_FILE="/var/log/clean_upload.log" # 执行清理,并记录日志 find "$UPLOAD_DIR" -type f -mtime +$RETENTION_DAYS -delete -print >> "$LOG_FILE" 2>&1 # 如果要清理空目录(可选) find "$UPLOAD_DIR" -type d -empty -delete -print >> "$LOG_FILE" 2>&1 echo "[$(date)] Cleanup completed. Deleted files older than $RETENTION_DAYS days from $UPLOAD_DIR." >> "$LOG_FILE"
定时执行(Crontab):
# 每天凌晨 3 点执行 0 3 * * * /usr/local/bin/clean_upload.sh
进阶:按文件名模式清理(如只清理 .tmp 或上报失败文件)
# 清理超过2小时的 .part 文件(上传中断的残留文件) find "$UPLOAD_DIR" -name "*.part" -type f -mmin +120 -delete # 清理包含"report_failed"的文件 find "$UPLOAD_DIR" -name "*_failed*" -type f -mtime +1 -delete
Windows 环境(PowerShell + 任务计划程序)
适用于 Windows Server 或本地开发环境。
PowerShell 脚本:
# 文件名: Clean-Upload.ps1
$uploadDir = "C:\Data\Upload"
$retentionDays = 7
$logFile = "C:\Logs\clean_upload.log"
$cutoffDate = (Get-Date).AddDays(-$retentionDays)
# 删除旧文件
Get-ChildItem -Path $uploadDir -Recurse -File | Where-Object {
$_.LastWriteTime -lt $cutoffDate
} | Remove-Item -Force -Verbose | Out-File -FilePath $logFile -Append
# 删除空目录
Get-ChildItem -Path $uploadDir -Recurse -Directory | Where-Object {
(Get-ChildItem $_.FullName -Recurse -File).Count -eq 0
} | Remove-Item -Force -Verbose | Out-File -FilePath $logFile -Append
Write-Output "[$(Get-Date)] Cleanup completed for files older than $retentionDays days." | Out-File -FilePath $logFile -Append
设置定时任务(任务计划程序):
- 触发器:每天凌晨
- 操作:启动程序
powershell.exe - 参数:
-ExecutionPolicy Bypass -File "C:\Scripts\Clean-Upload.ps1"
内存/临时文件清理(应对高并发写爆磁盘)
如果上报文件是短期高频产生(如日志、监控数据),且能接受“按大小”清理:
Python 脚本(跨平台,更灵活):
import os
import time
import shutil
import logging
UPLOAD_DIR = "/data/upload"
MAX_SIZE_GB = 10 # 目录总大小超过此值则触发清理
RETENTION_HOURS = 24 # 保留最近24小时的文件
logging.basicConfig(filename='clean_script.log', level=logging.INFO)
def get_dir_size_gb(path):
total = 0
for dirpath, dirnames, filenames in os.walk(path):
for f in filenames:
fp = os.path.join(dirpath, f)
if os.path.exists(fp):
total += os.path.getsize(fp)
return total / (1024**3)
def clean_by_time(path, hours):
now = time.time()
cutoff = now - hours * 3600
removed_count = 0
for root, dirs, files in os.walk(path):
for file in files:
file_path = os.path.join(root, file)
try:
if os.path.getmtime(file_path) < cutoff:
os.remove(file_path)
removed_count += 1
except Exception as e:
logging.error(f"Error removing {file_path}: {e}")
logging.info(f"Cleaned {removed_count} files older than {hours} hours.")
if __name__ == "__main__":
if get_dir_size_gb(UPLOAD_DIR) > MAX_SIZE_GB:
clean_by_time(UPLOAD_DIR, RETENTION_HOURS)
适用场景: 磁盘空间不足时自动触发,防止服务因写满磁盘而崩溃。
复杂策略(使用 logrotate 工具)
如果上报文件是按天/小时切割的日志文件,logrotate 是 Linux 上最专业的工具。
配置文件 /etc/logrotate.d/upload_report:
/data/upload/*.log {
daily # 每天轮转
rotate 7 # 只保留最近7个轮转文件
compress # 压缩旧文件
delaycompress # 延迟一天压缩
missingok # 忽略缺失文件
notifempty # 空文件不轮转
create 0644 www-data www-data # 创建新文件的权限和所有者
postrotate # 轮转后执行命令(如重载应用)
systemctl reload nginx 2>/dev/null || true
endscript
}
关键注意事项(安全红线)
-
绝对不要用
rm -rf对变量进行拼接:# 错误示例($dir 为空或 / 则灾难) rm -rf $dir/* # 正确做法:先判断变量非空,再加保险 if [ -d "$UPLOAD_DIR" ]; then find "$UPLOAD_DIR" -delete fi -
先测试,再上线:
- 先用
-print或ls看会删哪些文件。 - 如果是 PowerShell,先用
-WhatIf参数模拟。
- 先用
-
日志和监控:
- 务必记录删除了哪些文件(
-print到日志)。 - 设置磁盘告警(如磁盘使用率 > 80% 发通知)。
- 务必记录删除了哪些文件(
-
并发安全:
- 如果脚本运行时还在写文件,用
.tmp后缀先写再重命名,然后只清理.tmp文件。
- 如果脚本运行时还在写文件,用
选择最适合你的组合
| 场景 | 推荐方案 |
|---|---|
| Linux 服务器,简单按天数清理 | Shell + Crontab |
| Windows Server | PowerShell + 任务计划程序 |
| 需要按磁盘大小动态清理 | Python 脚本 + 定时任务 |
| 上报文件是切割日志 | logrotate |
| 需要在清理后通知应用或跑后续任务 | 脚本末尾加 curl 或 systemctl |
如果需要针对你的具体业务(如文件命名规则、上报状态标记)定制清理策略,可以告诉我更多细节,我可以提供更精准的脚本。