Files
ljwx-harbor/brew/brew-verify.sh
T
bruno 435834dc79 feat: Harbor 版本化配置
- 添加 Harbor 快速恢复脚本 (harbor-quick-restore.sh)
- 添加完整恢复指南 (HARBOR-RESTORE-GUIDE.md)
- 添加版本信息文件 (VERSION.md)
- 更新 .gitignore 排除敏感数据
- 配置 harbor git remote
- 修复 Cloudflare Tunnel 配置

系统重装后可通过以下命令快速恢复:
git clone http://192.168.1.83:33000/gao/ljwx-harbor.git
cd ljwx-harbor
./harbor-quick-restore.sh
2026-02-27 08:12:30 +08:00

328 lines
8.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# ========================================
# Homebrew 备份验证工具
# 功能:验证备份文件完整性和有效性
# ========================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OPS_DIR="${HOME}/ops"
BACKUP_DIR="${OPS_DIR}/backups"
# 颜色输出
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${GREEN}✓${NC} $1"; }
log_warn() { echo -e "${YELLOW}⚠${NC} $1"; }
log_error() { echo -e "${RED}✗${NC} $1"; }
log_section() { echo -e "${BLUE}━━━${NC} $1"; }
# 验证 Brewfile
verify_brewfile() {
local brewfile="$1"
log_section "验证 Brewfile: $(basename "$brewfile")"
# 检查文件是否存在
if [ ! -f "$brewfile" ]; then
log_error "文件不存在"
return 1
fi
# 检查文件是否为空
if [ ! -s "$brewfile" ]; then
log_error "文件为空"
return 1
fi
# 文件大小
local size=$(du -h "$brewfile" | cut -f1)
log_info "文件大小: $size"
# 统计内容
local brew_count=$(grep -c "^brew " "$brewfile" 2>/dev/null || echo 0)
local cask_count=$(grep -c "^cask " "$brewfile" 2>/dev/null || echo 0)
local tap_count=$(grep -c "^tap " "$brewfile" 2>/dev/null || echo 0)
echo " - Formulae: $brew_count"
echo " - Casks: $cask_count"
echo " - Taps: $tap_count"
# 基本语法检查
local errors=0
# 检查是否有明显的语法错误
if grep -q "^[^#]*Error" "$brewfile" 2>/dev/null; then
log_warn "可能包含错误信息"
errors=$((errors + 1))
fi
# 检查基本格式
if ! grep -q "^brew\|^cask\|^tap\|^#" "$brewfile" 2>/dev/null; then
log_warn "格式可能不正确"
errors=$((errors + 1))
fi
if [ $errors -eq 0 ]; then
log_info "Brewfile 格式正确"
return 0
else
log_warn "发现 $errors 个潜在问题"
return 1
fi
}
# 验证压缩包
verify_archive() {
local archive="$1"
log_section "验证压缩包: $(basename "$archive")"
# 检查文件是否存在
if [ ! -f "$archive" ]; then
log_error "文件不存在"
return 1
fi
# 文件大小
local size=$(du -h "$archive" | cut -f1)
log_info "文件大小: $size"
# 测试压缩包完整性
if tar -tzf "$archive" > /dev/null 2>&1; then
log_info "压缩包完整"
# 列出内容
echo " 内容:"
tar -tzf "$archive" | sed 's/^/ /'
return 0
else
log_error "压缩包损坏"
return 1
fi
}
# 比较两个 Brewfile
compare_brewfiles() {
local file1="$1"
local file2="$2"
log_section "比较 Brewfile"
echo " 文件1: $(basename "$file1")"
echo " 文件2: $(basename "$file2")"
echo
if [ ! -f "$file1" ] || [ ! -f "$file2" ]; then
log_error "文件不存在"
return 1
fi
# 提取包列表
local temp1=$(mktemp)
local temp2=$(mktemp)
grep "^brew\|^cask" "$file1" | sort > "$temp1"
grep "^brew\|^cask" "$file2" | sort > "$temp2"
# 统计差异
local added=$(comm -13 "$temp1" "$temp2" | wc -l | tr -d ' ')
local removed=$(comm -23 "$temp1" "$temp2" | wc -l | tr -d ' ')
local common=$(comm -12 "$temp1" "$temp2" | wc -l | tr -d ' ')
echo " 共同包: $common"
echo " 新增包: $added"
echo " 移除包: $removed"
if [ $added -gt 0 ]; then
echo
echo " 新增的包:"
comm -13 "$temp1" "$temp2" | sed 's/^/ /'
fi
if [ $removed -gt 0 ]; then
echo
echo " 移除的包:"
comm -23 "$temp1" "$temp2" | sed 's/^/ /'
fi
rm -f "$temp1" "$temp2"
}
# 验证所有备份
verify_all() {
log_section "验证所有备份文件"
echo
# 验证最新快照
if [ -f "${BACKUP_DIR}/Brewfile.latest" ]; then
verify_brewfile "${BACKUP_DIR}/Brewfile.latest"
echo
else
log_warn "未找到 Brewfile.latest"
echo
fi
# 验证最近的 Brewfile 备份
echo "最近的 Brewfile 备份:"
local brewfiles=$(find "$BACKUP_DIR" -name "Brewfile_*.brew" -type f | sort -r | head -5)
if [ -n "$brewfiles" ]; then
local count=0
while IFS= read -r file; do
count=$((count + 1))
echo "[$count] $(basename "$file") - $(ls -lh "$file" | awk '{print $5}')"
done <<< "$brewfiles"
echo
else
log_warn "未找到 Brewfile 备份"
echo
fi
# 验证最近的压缩包备份
echo "最近的压缩包备份:"
local archives=$(find "$BACKUP_DIR" -name "brew_backup_*.tar.gz" -type f | sort -r | head -5)
if [ -n "$archives" ]; then
local count=0
while IFS= read -r file; do
count=$((count + 1))
echo "[$count] $(basename "$file") - $(ls -lh "$file" | awk '{print $5}')"
done <<< "$archives"
echo
else
log_warn "未找到压缩包备份"
echo
fi
}
# 健康检查
health_check() {
log_section "Homebrew 健康检查"
# 检查 Homebrew 是否安装
if command -v brew &> /dev/null; then
log_info "Homebrew 已安装: $(brew --version | head -n1)"
else
log_error "Homebrew 未安装"
return 1
fi
# 检查备份目录
if [ -d "$BACKUP_DIR" ]; then
log_info "备份目录存在: $BACKUP_DIR"
local backup_count=$(find "$BACKUP_DIR" -name "Brewfile_*.brew" -type f | wc -l | tr -d ' ')
echo " - Brewfile 备份: $backup_count 个"
local archive_count=$(find "$BACKUP_DIR" -name "brew_backup_*.tar.gz" -type f | wc -l | tr -d ' ')
echo " - 压缩包备份: $archive_count 个"
else
log_warn "备份目录不存在"
fi
# 检查最新快照
if [ -f "${BACKUP_DIR}/Brewfile.latest" ]; then
local age=$(find "${BACKUP_DIR}/Brewfile.latest" -mtime +7 2>/dev/null | wc -l | tr -d ' ')
if [ "$age" -gt 0 ]; then
log_warn "最新快照超过 7 天未更新"
else
log_info "最新快照是最近的"
fi
else
log_warn "未找到最新快照"
fi
# 运行 brew doctor(简化版)
echo
log_section "运行 brew doctor"
if brew doctor 2>&1 | head -20; then
log_info "Homebrew 状态正常"
else
log_warn "Homebrew 可能需要修复"
fi
}
# 显示帮助
show_help() {
cat << 'EOF'
Homebrew 备份验证工具
用法: brew-verify.sh <命令> [参数]
命令:
brewfile <文件> 验证指定的 Brewfile
archive <文件> 验证指定的压缩包
compare <文件1> <文件2> 比较两个 Brewfile
all 验证所有备份文件
health 健康检查
help 显示此帮助信息
示例:
# 验证最新快照
./brew-verify.sh brewfile ~/ops/backups/Brewfile.latest
# 验证压缩包
./brew-verify.sh archive ~/ops/backups/brew_backup_2025-12-28.tar.gz
# 比较两个备份
./brew-verify.sh compare Brewfile.latest Brewfile_2025-12-27.brew
# 验证所有备份
./brew-verify.sh all
# 健康检查
./brew-verify.sh health
EOF
}
# 主函数
main() {
case "${1:-}" in
brewfile)
if [ -z "${2:-}" ]; then
log_error "请指定 Brewfile 路径"
exit 1
fi
verify_brewfile "$2"
;;
archive)
if [ -z "${2:-}" ]; then
log_error "请指定压缩包路径"
exit 1
fi
verify_archive "$2"
;;
compare)
if [ -z "${2:-}" ] || [ -z "${3:-}" ]; then
log_error "请指定两个 Brewfile 路径"
exit 1
fi
compare_brewfiles "$2" "$3"
;;
all)
verify_all
;;
health)
health_check
;;
help|--help|-h)
show_help
;;
*)
echo "错误: 未知命令 '${1:-}'"
echo
show_help
exit 1
;;
esac
}
main "$@"