最可靠方法是用 find /backup -name "*.tar.gz" -mtime +30 -delete 一行清理;务必加 -maxdepth 1 防误删子目录,先用 -ls 测试,脚本中需加日志和错误检查,并用绝对路径配置 cron。

find 命令直接删过期 .tar.gz 文件最可靠
Linux 下清理旧备份,别写循环遍历 + stat 判断,效率低还容易出错。用 find 一行搞定,它原生支持按修改时间(-mtime)或访问时间筛选,且能安全执行删除。
假设备份包统一放在 /backup/,后缀是 .tar.gz,要删 30 天前的:
find /backup -name "*.tar.gz" -mtime +30 -delete
注意:-mtime +30 表示“修改时间早于 30×24 小时前”,即第 31 天及更早的文件——这正是“超过 30 天”的准确含义。别用 +29 或 >30,find 的 -mtime 是向下取整计算的。
- 先测试:把
-delete换成-ls,确认列出的确实是目标文件 - 避免误删:确保路径末尾没多加
/*,比如/backup/*可能因 shell 展开导致意外行为,find内部匹配更安全 - 如果备份包是用
gzip单独压缩(如.tar+.gz分离),需改用-name "*.tar" -o -name "*.gz"并用括号分组
脚本里必须加日志和错误防护
自动清理不能黑盒运行。没日志,哪天删错了都找不到证据;没错误检查,磁盘满或权限问题导致 find 失败,脚本却静默退出,等于没清理。
基础防护写法:
#!/bin/bash
LOG="/var/log/clean-backup.log"
echo "[$(date)] Start cleanup" >> "$LOG"
if ! find /backup -name "*.tar.gz" -mtime +30 -delete >> "$LOG" 2>&1; then
echo "[$(date)] ERROR: find failed" >> "$LOG"
exit 1
fi
echo "[$(date)] Done" >> "$LOG"- 用
>> "$LOG" 2>&1把 stdout 和 stderr 都记下,否则删了什么、哪里报错全看不见 -
if ! ...; then exit 1确保上游任务(比如 cron)能感知失败,而不是假装成功 - 别在脚本里用
cd /backup && find . -name ...—— 路径硬编码更稳,cd失败会导致后续命令在错误目录执行
cron 定时执行要注意 PATH 和用户权限
放进 crontab 后常见问题:手动运行脚本 OK,cron 里却删不掉文件。大概率是环境变量差异导致的权限或路径问题。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
正确做法:
- 用绝对路径调用脚本,例如
0 2 * * * /usr/local/bin/clean-backup.sh,不要用~/clean.sh - 在 crontab 条目开头显式声明 PATH:
PATH=/usr/local/bin:/usr/bin:/bin - 确认 cron 是以哪个用户运行的(比如
root还是backupuser),该用户必须对/backup有读+写权限;若备份是root打的包,普通用户可能删不掉 - 测试 cron 环境:临时加一行
* * * * * env > /tmp/cron-env.txt,对比手动执行env的输出差异
用 -maxdepth 1 防止递归进子目录误删
如果 /backup 下有子目录(比如 /backup/2024-01/、/backup/2024-02/),默认 find 会递归进去找所有 .tar.gz,可能删掉不该动的目录结构。
加 -maxdepth 1 限定只扫一级:
find /backup -maxdepth 1 -name "*.tar.gz" -mtime +30 -delete
这个参数非常关键,但极易被忽略。不加的话,哪怕你只打算清理根目录下的包,find 也会钻进每个子目录层层查找——而子目录里的旧包,很可能属于另一套归档策略,不该由这个脚本处理。
如果真需要清理子目录里的备份,得明确设计规则,比如按目录名日期过滤,而不是依赖 -mtime 全局扫描。

















