#!/bin/bash # amber-pm-base-overrider # 功能:检查 /opt/apm-dummy/files-to-override 下的文件,并覆盖到所有包含 # /var/lib/apm/文件夹/files 的 /var/lib/apm/文件夹/files/ace-env 下 # 日志函数 log_warn() { echo -e "[\e[33mWARN\e[0m]: \e[1m$*\e[0m"; } log_error() { echo -e "[\e[31mERROR\e[0m]: \e[1m$*\e[0m"; } log_info() { echo -e "[\e[96mINFO\e[0m]: \e[1m$*\e[0m"; } log_debug() { echo -e "[\e[32mDEBUG\e[0m]: \e[1m$*\e[0m"; } # 配置 OVERRIDE_SOURCE="/opt/apm-dummy/files-to-override" APM_BASE_DIR="/var/lib/apm" # 显示帮助信息 show_help() { cat </files/ace-env 目录下。 EOF } # 解析参数 VERBOSE=false DRY_RUN=false while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_help exit 0 ;; -v|--verbose) VERBOSE=true shift ;; -n|--dry-run) DRY_RUN=true shift ;; *) log_error "未知选项: $1" show_help exit 1 ;; esac done # 检查源目录是否存在 if [ ! -d "$OVERRIDE_SOURCE" ]; then log_error "源目录不存在: $OVERRIDE_SOURCE" exit 1 fi # 检查源目录是否为空 if [ -z "$(ls -A "$OVERRIDE_SOURCE" 2>/dev/null)" ]; then exit 0 fi $VERBOSE && log_info "源目录: $OVERRIDE_SOURCE" # 检查 APM 基础目录是否存在 if [ ! -d "$APM_BASE_DIR" ]; then exit 0 fi # 计数器 OVERRIDE_COUNT=0 ERROR_COUNT=0 HAS_CHANGES=false # 遍历 /var/lib/apm/ 下的所有子目录 for pkg_dir in "$APM_BASE_DIR"/*/; do # 去掉末尾的斜杠 pkg_dir="${pkg_dir%/}" # 检查是否是目录 if [ ! -d "$pkg_dir" ]; then continue fi pkg_name=$(basename "$pkg_dir") files_dir="$pkg_dir/files" target_dir="$files_dir/ace-env" # 检查是否存在 files 目录 if [ ! -d "$files_dir" ]; then $VERBOSE && log_debug "跳过 $pkg_name: 不存在 files 目录" continue fi # 检查是否存在 ace-env 目录 if [ ! -d "$target_dir" ]; then $VERBOSE && log_debug "跳过 $pkg_name: 不存在 ace-env 目录" continue fi # 检查是否有文件需要更新(比较源文件和目标文件) NEED_UPDATE=false while IFS= read -r -d '' file; do rel_path="${file#$OVERRIDE_SOURCE/}" target_file="$target_dir/$rel_path" # 如果目标文件不存在或源文件更新,则需要更新 if [ ! -e "$target_file" ] || [ "$file" -nt "$target_file" ]; then NEED_UPDATE=true break fi done < <(find "$OVERRIDE_SOURCE" -type f -print0 2>/dev/null) # 如果没有需要更新的文件,跳过 if [ "$NEED_UPDATE" = false ]; then $VERBOSE && log_debug "跳过 $pkg_name: 文件已是最新" continue fi HAS_CHANGES=true $VERBOSE && log_info "处理包: $pkg_name" # 使用 rsync 或 cp 进行覆盖 if [ "$DRY_RUN" = true ]; then $VERBOSE && log_info "[试运行] 将覆盖文件到: $target_dir" find "$OVERRIDE_SOURCE" -type f | while read -r file; do rel_path="${file#$OVERRIDE_SOURCE/}" target_file="$target_dir/$rel_path" echo " 将复制: $rel_path -> $target_file" done ((OVERRIDE_COUNT++)) else # 使用 cp -r 进行递归复制,保留权限 if cp -rL "$OVERRIDE_SOURCE"/* "$target_dir/" 2>/dev/null; then $VERBOSE && log_info "成功覆盖到: $target_dir" ((OVERRIDE_COUNT++)) else log_error "覆盖失败: $target_dir" ((ERROR_COUNT++)) fi fi done # 只有在有改动或 verbose 模式时才输出统计信息 if [ "$HAS_CHANGES" = true ] || [ "$VERBOSE" = true ]; then $VERBOSE && log_info "====================================" $VERBOSE && log_info "覆盖操作完成" log_info "成功处理: $OVERRIDE_COUNT 个包" if [ "$DRY_RUN" = true ]; then log_info "[试运行模式] 未实际执行覆盖" fi if [ $ERROR_COUNT -gt 0 ]; then log_error "失败: $ERROR_COUNT 个包" fi fi exit 0