前言

前两天写过一篇《使用绿联NAS备份服务器数据》的文章。

但是想备份服务器的其他内容,只能原封不动的搬运过来,不能做到压缩备份,这时候就得需要一个可以自动打包数据并压缩的Shell任务了。

打包完成之后,我们再在NAS使用远程下载文件的定时任务去拉取这个压缩备份,就能做到备份自定义文件了,非常灵活通用,比如:想备份Minecraft服务器的数据,直接把存档文件夹压缩保存在某个指定目录,NAS直接远程拉取这个目录就能达到备份Minecraft存档的功能了。

理论可行,实践开始。

开始

其实只需要一个Shell脚本,然后在1Panel中配置计划任务就行了,非常简单,这里就只需要给出Shell脚本,以及脚本功能、如何使用就行了。

Shell脚本

脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/bash

#######################################
# 用户配置区域 #
# 请修改以下配置以满足你的需求 #
#######################################

# 备份目标目录(压缩包将保存在这里)
TARGET_DIR="/opt/backup/minecraft-general-plugin"

# 要备份的源目录列表(可以包含文件或目录)
SOURCE_DIRS=(
"/opt/game/minecraft/general-plugin-server" # 备份MC插件服务器
#"/root/2222" # 备份图片
)

# 压缩包名称前缀(会自动添加时间戳)
ARCHIVE_PREFIX="minecraft_general_plugin_server"

# 临时目录前缀(会自动添加随机字符串)
TEMP_DIR_PREFIX="backup_temp"

# 保留的备份数量(设置为0表示不删除旧备份)
KEEP_COUNT=1

#######################################
# 脚本主体部分 #
#######################################

# 检查目标目录是否存在
if [ ! -d "$TARGET_DIR" ]; then
echo "错误: 目标目录 '$TARGET_DIR' 不存在,正在创建..."
mkdir -p "$TARGET_DIR" || {
echo "错误: 无法创建目标目录 '$TARGET_DIR'"
exit 1
}
fi

# 创建临时目录
temp_dir=$(mktemp -d -p "$TARGET_DIR" "${TEMP_DIR_PREFIX}_XXXXXX")
if [ $? -ne 0 ]; then
echo "错误: 无法创建临时目录"
exit 1
fi

echo "开始备份操作..."
echo "目标目录: $TARGET_DIR"
echo "临时目录: $temp_dir"
echo "保留最新的 $KEEP_COUNT 个备份"
echo "--------------------------------"

# 复制所有源目录到临时目录
for src in "${SOURCE_DIRS[@]}"; do
# 跳过注释和空行
[[ "$src" =~ ^[[:space:]]*# ]] && continue
[[ -z "$src" ]] && continue

if [ ! -e "$src" ]; then
echo "警告: '$src' 不存在,跳过"
continue
fi

echo "正在复制: $src"
cp -r "$src" "$temp_dir/"
if [ $? -ne 0 ]; then
echo "错误: 复制 '$src' 失败"
rm -rf "$temp_dir"
exit 1
fi
done

# 创建压缩包
timestamp=$(date +%Y%m%d_%H%M%S)
archive_name="${ARCHIVE_PREFIX}_${timestamp}.tar.gz"
echo "--------------------------------"
echo "正在创建压缩包: $archive_name"
tar -czf "$TARGET_DIR/$archive_name" -C "$temp_dir" .

# 清理临时目录
echo "清理临时文件..."
rm -rf "$temp_dir"

echo "--------------------------------"
echo "备份完成!"
echo "压缩包已保存到: $TARGET_DIR/$archive_name"

# 清理旧备份文件(如果KEEP_COUNT大于0)
if [ $KEEP_COUNT -gt 0 ]; then
echo "--------------------------------"
echo "正在清理旧备份文件,保留最新的 $KEEP_COUNT 个..."

# 获取匹配的备份文件列表,按修改时间从旧到新排序
backup_files=($(ls -tr "$TARGET_DIR/${ARCHIVE_PREFIX}"_*.tar.gz 2>/dev/null))

total_files=${#backup_files[@]}
if [ $total_files -gt $KEEP_COUNT ]; then
files_to_delete=$((total_files - KEEP_COUNT))
echo "发现 $total_files 个备份文件,将删除最旧的 $files_to_delete 个..."

# 删除最旧的文件
for ((i=0; i<files_to_delete; i++)); do
echo "删除: ${backup_files[$i]}"
rm -f "${backup_files[$i]}"
done
echo "已删除 $files_to_delete 个旧备份文件"
else
echo "当前备份文件数量: $total_files,未超过保留数量 $KEEP_COUNT,无需清理"
fi
else
echo "--------------------------------"
echo "配置为不删除旧备份文件 (KEEP_COUNT=0)"
fi

echo "--------------------------------"
echo "所有操作完成!"

功能说明

将指定的一个或多个文件夹/文件,打包到tar.gz包中,源文件不受任何影响。

tar.gz压缩包的名称会带上时间,可指定保存压缩包的个数,超出则删除最旧的压缩包。

参数说明

  • TARGET_DIR:压缩包保存的文件夹路径
  • SOURCE_DIRS:需要被压缩的内容,可以是多个,可以是文件夹或文件
  • ARCHIVE_PREFIX:压缩包的前缀,最终压缩包的名称会带上时间后缀
  • TEMP_DIR_PREFIX:临时目录的前缀,最终临时目录会带上随机后缀,打包完成后自动删除
  • KEEP_COUNT:保存的压缩包个数,多次执行脚本时,会自动清理多余的压缩包,删除最旧的

1Panel计划任务

其实只需要能够定时执行脚本就行了,没了解过其他能定时执行脚本的工具,由于服务器是由1Panel管理的,这里直接就使用1Panel的计划任务了,按照以下步骤配置即可,非常简单。

进入计划任务菜单,点击创建计划任务

  • 任务类型:Shell脚本
  • 任务名称:任意
  • 执行周期:根据需求,我这里是游戏存档,设置成了一天一次,凌晨执行
  • 脚本内容:录入上面的脚本,根据配置说明修改
  • 保留份数:默认7天足够了

点击确认,计划任务就已经弄好了,想要使用NAS远程备份,就直接备份脚本中TARGET_DIR配置的文件夹路径就行了。