如何在循环中用unzip -t检测zip完整性并捕获错误发送邮件
备份zip完整性自动检测脚本实现方案
优化后完整脚本(单错误单告警)
#!/bin/bash # 备份根目录,替换为你实际的路径 BACKUP_DIR="/SOMEDIR/Backups/" # 告警接收邮箱,替换为你的实际邮箱 NOTIFY_EMAIL="someemail@someone.co.uk" # 遍历所有zip文件,兼容带空格/特殊字符的文件名 find "$BACKUP_DIR" -type f -iname "*.zip" -print0 | while IFS= read -r -d '' zip_file; do # 执行完整性检测,合并捕获标准输出和标准错误 test_output=$(unzip -t "$zip_file" 2>&1) # 检测unzip返回码,非0表示校验失败 if [ $? -ne 0 ]; then mail_content="备份ZIP文件完整性检测失败 文件路径:$zip_file ==================== 错误详情: $test_output" echo "$mail_content" | mail -s "【备份告警】ZIP文件检测失败" "$NOTIFY_EMAIL" fi done
优化后完整脚本(多错误合并告警,避免轰炸邮箱)
#!/bin/bash BACKUP_DIR="/SOMEDIR/Backups/" NOTIFY_EMAIL="someemail@someone.co.uk" # 临时错误日志路径 ERROR_TMP_LOG="/tmp/zip_backup_check_error.log" # 清空上次运行的错误日志 > "$ERROR_TMP_LOG" # 遍历所有zip文件 find "$BACKUP_DIR" -type f -iname "*.zip" -print0 | while IFS= read -r -d '' zip_file; do test_output=$(unzip -t "$zip_file" 2>&1) if [ $? -ne 0 ]; then echo "----------------------------------------" >> "$ERROR_TMP_LOG" echo "异常文件路径:$zip_file" >> "$ERROR_TMP_LOG" echo "错误信息:" >> "$ERROR_TMP_LOG" echo "$test_output" >> "$ERROR_TMP_LOG" echo "" >> "$ERROR_TMP_LOG" fi done # 错误日志非空则发送统一告警 if [ -s "$ERROR_TMP_LOG" ]; then failed_count=$(grep -c '异常文件路径' "$ERROR_TMP_LOG") echo "本次检测共发现${failed_count}个损坏的备份ZIP文件,详情如下: $(cat $ERROR_TMP_LOG)" | mail -s "【备份告警】${failed_count}个ZIP文件检测失败" "$NOTIFY_EMAIL" fi # 清理临时文件 rm -f "$ERROR_TMP_LOG"
核心优化说明
- 用
find -print0+while read -d ''的遍历方式,完美兼容文件名带空格、换行、特殊字符的场景,解决原for循环拆分文件名的bug - 直接通过
unzip -t的返回码判断校验结果,比单独匹配某一类错误关键字更全面,所有校验失败场景(文件损坏、分卷包不完整、密码错误等)都能捕获 2>&1合并标准输出和标准错误,完整保留所有错误信息,不会漏捕获- 无需临时文件存储单文件检测结果,直接用变量存储输出,避免临时文件读写权限、覆盖冲突问题
- 邮件内容主动拼接异常文件的绝对路径,无需从错误日志中反向查找对应文件
定时运行配置
给脚本添加执行权限:chmod +x /path/to/your/check_zip_script.sh
使用crontab配置定时执行,比如每天凌晨2点运行检测:
执行crontab -e,添加如下行:
0 2 * * * /path/to/your/check_zip_script.sh >/dev/null 2>&1
注:确保服务器已安装mailx或sendmail组件,mail命令可正常使用。
内容的提问来源于stack exchange,提问作者Dave Hamilton
相关产品推荐
相关产品推荐

