#!/bin/bash # 功能:按年份/月份打包 /home/system 下的日志文件 # 用法: # ./xz_log_all.sh 打包上个月的日志 # ./xz_log_all.sh 2025 打包2025年全年 # ./xz_log_all.sh 202503 打包2025年3月 # 注意:删除原始文件功能在89行,可自行注释或开启 set -u # -------------------- 参数解析 -------------------- if [ $# -eq 0 ]; then # 无参数:打包上个月 match_str=$(date -d "$(date +%Y-%m-01) -1 month" +%Y%m) echo "未指定年份/月份,将打包上个月 ($match_str) 的日志。" elif [ $# -eq 1 ]; then param="$1" if [[ "$param" =~ ^[0-9]{4}$ ]]; then match_str="$param" echo "将打包 $match_str 年全年的日志。" elif [[ "$param" =~ ^[0-9]{6}$ ]]; then match_str="$param" echo "将打包 $match_str 年月的日志。" else echo "错误:参数必须是 4 位年份或 6 位年月(如 2025 或 202503)" exit 1 fi else echo "错误:参数数量不正确,最多接受一个参数。" exit 1 fi # -------------------- 临时文件 -------------------- dir_all=$(mktemp) dir_target=$(mktemp) trap "rm -f $dir_all $dir_target" EXIT # -------------------- 扫描目录 -------------------- echo "正在扫描 /home/system 下的日志目录..." find /home/system -type f -name "*.log" -printf "%h\n" 2>/dev/null | sort -u > "$dir_all" echo "正在检查各目录中是否存在匹配 $match_str 的日志文件..." while IFS= read -r dir; do [ -d "$dir" ] || continue if find "$dir" -maxdepth 1 -type f -name "*${match_str}*.log" -printf "%f\n" 2>/dev/null | grep -q .; then echo "$dir" >> "$dir_target" fi done < "$dir_all" if [ ! -s "$dir_target" ]; then echo "未找到任何包含匹配 $match_str 的日志的目录,退出。" exit 0 fi echo "找到以下匹配的目录(共 $(wc -l < "$dir_target") 个):" cat -n "$dir_target" | sed 's/^/ /' read -p "手动执行前请查看该脚本是否开启删除功能,确认后再继续,是否开始打包这些目录中的日志?(y/N) " -r confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then echo "操作已取消。" exit 0 fi # -------------------- 执行打包 -------------------- success_count=0 fail_count=0 total=$(wc -l < "$dir_target") archive_name="${match_str}.tar.xz" echo "开始打包(共 $total 个目录)..." while IFS= read -r dir; do current=$((success_count + fail_count + 1)) echo "[$current/$total] 正在处理目录:$dir" # 使用子 shell 处理单个目录 ( cd "$dir" < /dev/null || exit 1 file_count=$(find . -maxdepth 1 -type f -name "*${match_str}*.log" -printf "%f\n" 2>/dev/null | wc -l) if [ "$file_count" -eq 0 ]; then echo " 目录中没有匹配的日志文件,跳过" exit 0 fi echo " 找到 $file_count 个文件,正在压缩..." if find . -maxdepth 1 -type f -name "*${match_str}*.log" -printf "%f\0" | tar --null -c -T - | xz -9 > "$archive_name"; then echo " ✓ 已生成 $archive_name" # 如需删除原始文件,取消下面注释(谨慎!) find . -maxdepth 1 -type f -name "*${match_str}*.log" -delete exit 0 else echo " ✗ 打包失败 $dir" >&2 exit 1 fi ) if [ $? -eq 0 ]; then ((success_count++)) else ((fail_count++)) fi done < "$dir_target" echo "完成!成功: $success_count, 失败: $fail_count" if [ $fail_count -gt 0 ]; then echo "请检查失败的目录。" fi echo "执行完成"