108 lines
3.6 KiB
Bash
108 lines
3.6 KiB
Bash
#!/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 "执行完成" |