find结合rm -rf执行后空目录未被删除的问题求助
Having a strange issue. Using a script to go through our backup folders and delete any folder not named like the 1st of the month (2023-05-01) and older than 60 days.
It works in the sense that it is going through and erasing the files from the folders but the dated folders themselves (and sub folders) remain.. empty.
What am I missing here.
find /backups/stores/ -maxdepth 2 -type d! -name '????-??-01' -mtime +60 -exec rm -rf {} \;
看起来你遇到的问题挺典型的,咱们一步步拆解看看哪里出了问题:
核心原因分析
你的原命令逻辑是找修改时间超过60天、命名不是每月1号格式的目录,然后用rm -rf删除。但出现空目录残留的情况,大概率是因为:
- 当你删除目录内的文件时,目录本身的修改时间(mtime)会被更新——相当于这个目录“被修改过”,导致
-mtime +60的条件不再满足,find就不会选中这些目录来删除了。 - 你可以先验证下:执行不带
-exec的find命令,看看输出里有没有那些空目录,确认它们是否真的符合-mtime +60的条件:find /backups/stores/ -maxdepth 2 -type d! -name '????-??-01' -mtime +60
解决方案
根据你的需求(删除非1号命名、且“过期”的备份目录),推荐两种更可靠的方式:
方式一:基于目录名称的日期判断(更贴合备份场景)
备份目录的名称就是备份日期,直接用名称里的日期来判断是否超过60天,比依赖目录的mtime更准确:
# 计算60天前的日期,格式统一为YYYY-MM-DD THRESHOLD=$(date -d '60 days ago' +%Y-%m-%d) # 遍历符合日期命名格式的目录,筛选出非1号且早于阈值的目录删除 find /backups/stores/ -maxdepth 2 -type d -regex '.*/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}'! -name '????-??-01' | while read DIR; do DIR_DATE=$(basename "$DIR") if [[ "$DIR_DATE" < "$THRESHOLD" ]]; then rm -rf "$DIR" fi done
方式二:分两步操作(先清文件,再删空目录)
如果希望先清理目录内的旧文件,再删除空的非1号目录,可以分两次执行find:
# 第一步:删除非1号目录下所有超过60天的文件(包括子目录里的) find /backups/stores/ -maxdepth 3 -type f! -path '*/????-??-01/*' -mtime +60 -exec rm -f {} \; # 第二步:删除所有空的非1号目录(包括嵌套的空目录) find /backups/stores/ -maxdepth 2 -type d! -name '????-??-01' -empty -exec rmdir {} \;
这里用-empty匹配空目录,rmdir只会删除空目录,比rm -rf更安全,避免误删有内容的目录。
备注:内容来源于stack exchange,提问作者Jeremy




