0%

登录VPS远程备份脚本

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
#!/bin/bash

# ================= 配置区域 =================
VPS_NAME="VPS-A"
VPS_IP="192.168.1.5"
VPS_PORT="22"
KEY_PATH="/home/user/.ssh/192.168.1.5.pem"

# 源目录 (VPS上的目录)
SOURCE_DIR="/app"

# 备份根目录 (fnos上的目录)
# 注意:脚本会在这个目录下自动创建日期文件夹,比如 .../vps_a/20231027
BASE_BACKUP_DIR="/vol2/1000/backup/192.168.1.5"

# 保留的版本数量
KEEP_COUNT=7
# ===========================================

# 1. 准备目录
if [ ! -d "$BASE_BACKUP_DIR" ]; then
mkdir -p "$BASE_BACKUP_DIR"
fi

cd "$BASE_BACKUP_DIR" || exit 1 # 如果进不去目录,直接报错退出

# 2. 寻找基准目录
LAST_BACKUP=$(ls -d */ 2>/dev/null | sort -r | head -n 1 | sed 's/\///')
TODAY_STR=$(date +%Y%m%d)
TARGET_DIR="${BASE_BACKUP_DIR}/${TODAY_STR}"

echo "[$VPS_NAME] 启动备份..."
echo "今天目标: $TARGET_DIR"

# 3. 构建参数
RSYNC_OPTS="-avz --delete"

if [ -n "$LAST_BACKUP" ] && [ "$LAST_BACKUP" != "$TODAY_STR" ]; then
echo "发现旧备份: [${LAST_BACKUP}],启用增量硬链接模式。"
RSYNC_OPTS="${RSYNC_OPTS} --link-dest=${BASE_BACKUP_DIR}/${LAST_BACKUP}"
else
echo "执行全量备份。"
fi

# 建立今日目录
mkdir -p "$TARGET_DIR"

# 4. 执行备份
rsync $RSYNC_OPTS -e "ssh -p $VPS_PORT -i $KEY_PATH" root@${VPS_IP}:${SOURCE_DIR}/ ${TARGET_DIR}/

# 捕获 rsync 的结果状态码
EXIT_CODE=$?

# 5. 判断结果
if [ $EXIT_CODE -eq 0 ]; then
echo "-------------------------------------"
echo "[$VPS_NAME] ✅ 备份成功!"

# 清理旧版本
echo "正在检查清理..."
ls -d */ | sort -r | tail -n +$((KEEP_COUNT + 1)) | xargs -I {} rm -rf {}
echo "完成。"

# 正常退出 (1Panel 显示成功)
exit 0
else
echo "-------------------------------------"
echo "[$VPS_NAME] ❌ 备份失败!(错误码: $EXIT_CODE)"
echo "请检查 SSH 连接、磁盘空间或 rsync 是否安装。"

# 如果失败,删掉今天生成的残缺文件夹,避免明天把它当做基准
rm -rf "$TARGET_DIR"

# 【关键】非0退出,强制 1Panel 标记为失败
exit 1
fi

欢迎关注我的其它发布渠道