如何修改CMS更新脚本以基于目录创建日期保留最新三个版本并自动删除旧备份
解决CMS备份脚本的版本筛选问题:基于日期而非名称排序
我明白你的痛点——版本命名规则的变更直接打破了原来基于名称的排序逻辑,改用目录的创建/修改日期来判断才是更可靠的方案,完全不受命名格式影响。下面给你两种可行的修改方案,按需选择:
方案1:基于修改时间筛选(简单通用)
这个方案用ls -t按目录的修改时间逆序排序(最新的在前),绝大多数场景下,CMS版本目录的修改时间就等于它的安装/创建时间,足够满足需求:
# 定义版本目录路径,确保变量引用安全 VERSION_DIR="$GHOSTDIR/versions" # 获取要保留的最新3个版本(按修改时间从新到旧取前3) keep_dirs=$(cd "$VERSION_DIR" && ls -1t */ | head -3) # 获取要删除的旧版本(从第4个条目开始) delete_dirs=$(cd "$VERSION_DIR" && ls -1t */ | tail -n +4) # 输出操作预览,先确认无误再执行删除 echo "=== 备份清理预览 ===" echo "将保留以下3个最新版本:" echo "$keep_dirs" echo "------------------------" echo "将删除以下旧版本:" echo "$delete_dirs" # 确认预览正确后,取消下面一行的注释执行实际删除 # cd "$VERSION_DIR" && echo "$delete_dirs" | xargs rm -rf
关键说明:
ls -1t */:-t参数让ls按修改时间从新到旧排序,-1确保每行一个目录,*/只匹配子目录,避免误操作文件。- 先运行脚本查看预览输出,确认要删除的目录是正确的旧版本,再取消删除命令的注释,防止误删重要文件。
方案2:基于创建时间筛选(更精准)
如果你的服务器上目录的修改时间可能和创建时间不一致(比如有人手动修改过目录内容),可以用这个严格基于创建时间的方案(注意:不同系统的创建时间获取命令有差异):
Linux系统版本:
VERSION_DIR="$GHOSTDIR/versions" cd "$VERSION_DIR" # 获取所有子目录的创建时间戳和路径,按时间逆序排序后提取路径 all_dirs=$(find . -maxdepth 1 -type d ! -name "." -printf "%W %p\n" | sort -nr | awk '{print $2}') # 分割出要保留和删除的目录 keep_dirs=$(echo "$all_dirs" | head -3) delete_dirs=$(echo "$all_dirs" | tail -n +4) # 输出预览 echo "=== 基于创建时间的备份清理预览 ===" echo "保留的最新3个版本:" echo "$keep_dirs" echo "------------------------" echo "将删除的旧版本:" echo "$delete_dirs" # 确认后取消注释执行删除 # echo "$delete_dirs" | xargs rm -rf
macOS系统版本:
macOS的find不支持-printf,需要用stat命令获取创建时间:
VERSION_DIR="$GHOSTDIR/versions" cd "$VERSION_DIR" # 遍历所有子目录,获取创建时间戳和路径,排序后提取路径 all_dirs=$(for dir in */; do stat -f "%B %N" "$dir"; done | sort -nr | awk '{print $2}') keep_dirs=$(echo "$all_dirs" | head -3) delete_dirs=$(echo "$all_dirs" | tail -n +4) # 输出预览 echo "=== 基于创建时间的备份清理预览 ===" echo "保留的最新3个版本:" echo "$keep_dirs" echo "------------------------" echo "将删除的旧版本:" echo "$delete_dirs" # 确认后取消注释执行删除 # echo "$delete_dirs" | xargs rm -rf
关键说明:
- 用
find或stat获取创建时间戳,再按时间戳逆序排序,彻底摆脱命名规则的干扰。 - 同样建议先看预览,确认无误再执行删除。
内容的提问来源于stack exchange,提问作者Peleke
相关产品推荐
相关产品推荐

