一键脚本
- 免交互式 默认备份到
/var/lib/fan-webssh/backup,保留 6 份(在线打包、不停服)
bash <(curl -sL https://raw.githubusercontent.com/meimolihan/fan-webssh/main/scripts/fan-webssh_backup.sh) "/var/lib/fan-webssh/backup" 6
| 用法 | 命令 | 说明 |
|---|---|---|
| 使用默认 | ./fan-webssh_backup.sh |
备份到默认目录(${APP_DIR}/backup),保留 6 份 |
| 只传保留份数 | ./fan-webssh_backup.sh 10 |
自定义保留 10 份 |
| 只传备份目录 | ./fan-webssh_backup.sh /data/bak |
自定义备份目录,保留 6 份 |
| 目录 + 保留数 | ./fan-webssh_backup.sh /data/bak 8 |
自定义目录与保留数量 |
| 顺序互换 | ./fan-webssh_backup.sh 8 /data/bak |
保留数在前,顺序兼容 |
补充说明
该脚本用于 fan-webssh 服务数据一键备份。在线打包、不停服:面板服务全程保持运行,无需 systemctl stop,避免因面板与脚本同属 systemd 服务而导致备份脚本被连带终止。脚本读取 /etc/fan-webssh.conf 得到 APP_DIR / DATA_DIR / BACKUP_DIR,直接 tar 打包数据目录生成备份文件(文件名精确到秒)→ 按保留数量自动清理过期备份。
功能特点
- 在线备份、不停服:不执行
systemctl stop,服务全程可用 - 免交互设计:无需任何输入,适合配合 crontab / 计划任务定时执行
- 参数兼容:支持「目录」「保留数」两种参数互换,
./fan-webssh_backup.sh 8 /data/bak与./fan-webssh_backup.sh /data/bak 8效果相同 - 秒级时间戳:备份文件名格式为
FanWebSSH-YYYY-MM-DD_HH-MM-SS.tar.gz,避免同名覆盖 - 自动清理:扫描备份目录中
FanWebSSH-*.tar.gz文件,按时间排序保留最新 N 份,删除过期文件 - 彩色日志:保存目录、保留数量、执行过程、删除列表均彩色高亮输出
- 默认安全:默认保留 6 份备份,防止意外删除
输出说明
脚本输出包含以下内容:
| 字段 | 说明 |
|---|---|
| 保存目录 | 备份文件存放路径 |
| 保留数量 | 设置的保留备份份数(默认 6) |
| 数据目录 | 安装记录中读取的数据目录路径 |
| 执行备份 | 正在生成的备份文件完整路径 |
| 删除列表 | 将要删除的过期备份文件列表 |
注意事项
- 需要 root 权限执行
- 数据目录优先读取安装记录
/etc/fan-webssh.conf,缺失时使用默认值/var/lib/fan-webssh/app/db - 备份目录需有写权限,脚本会自动
mkdir -p创建目录 - 备份期间服务不会停机,随时可执行
- 默认备份目录为
${APP_DIR}/backup(安装时写入配置),可通过参数覆盖 - 清理逻辑基于文件名时间戳排序,确保删除的是最旧的备份
- 建议配合定时任务(crontab / 计划任务)每日执行一次
定时任务示例
# 下载脚本到系统目录
curl -fsSL https://raw.githubusercontent.com/meimolihan/fan-webssh/main/scripts/fan-webssh_backup.sh -o /usr/local/bin/fan-webssh_backup
# 增加执行权限
chmod +x /usr/local/bin/fan-webssh_backup
# 追加定时任务(防重复追加)
(crontab -l 2>/dev/null | grep -Fq '/usr/local/bin/fan-webssh_backup /var/lib/fan-webssh/backup 6') || (crontab -l 2>/dev/null; echo '30 2 * * * /usr/local/bin/fan-webssh_backup /var/lib/fan-webssh/backup 6 >> /var/log/fan-webssh_backup.log 2>&1') | crontab -
# 查看日志
cat /var/log/fan-webssh_backup.log
脚本源码
#!/bin/bash
set -uo pipefail
# ================== terminal colors ==================
list_color_init() {
export gl_hui=$'\033[38;5;59m'
export gl_hong=$'\033[38;5;9m'
export gl_lv=$'\033[38;5;10m'
export gl_huang=$'\033[38;5;11m'
export gl_lan=$'\033[38;5;32m'
export gl_bai=$'\033[38;5;15m'
export gl_zi=$'\033[38;5;13m'
export gl_bufan=$'\033[38;5;14m'
export reset=$'\033[0m'
}
list_color_init
# 默认值
BACKUP_DIR=""
KEEP_NUM=6
SERVICE="fan-webssh"
CONFIG_FILE="/etc/fan-webssh.conf"
APP_DIR="/var/lib/fan-webssh"
DATA_DIR="/var/lib/fan-webssh/app/db"
# 从安装记录读取安装目录/数据目录/备份目录(不存在时使用默认值)
if [ -f "${CONFIG_FILE}" ]; then
while IFS='=' read -r KEY VALUE; do
KEY=$(printf '%s' "$KEY" | tr -d ' ')
[ "$KEY" = "APP_DIR" ] && [ -n "$VALUE" ] && APP_DIR="${VALUE}"
[ "$KEY" = "DATA_DIR" ] && [ -n "$VALUE" ] && DATA_DIR="${VALUE}"
[ "$KEY" = "BACKUP_DIR" ] && [ -n "$VALUE" ] && BACKUP_DIR="${VALUE}"
done < "${CONFIG_FILE}"
fi
BACKUP_DIR="${BACKUP_DIR:-${APP_DIR}/backup}"
# 参数解析,支持两种传参顺序可互换
# 用法示例:
# ./fan-webssh_backup.sh # 使用默认
# ./fan-webssh_backup.sh 10 # 只传保留份数
# ./fan-webssh_backup.sh /data/bak # 只传备份目录
# ./fan-webssh_backup.sh /data/bak 8 # 目录 保留数
# ./fan-webssh_backup.sh 8 /data/bak # 保留数 目录,顺序互换兼容
parse_args() {
local p1="${1:-}"
local p2="${2:-}"
if [[ -z "${p1}" ]]; then
return
fi
if [[ "${p1}" =~ ^[0-9]+$ ]]; then
KEEP_NUM="${p1}"
if [[ -n "${p2}" ]]; then
BACKUP_DIR="${p2}"
fi
else
BACKUP_DIR="${p1}"
if [[ -n "${p2}" && "${p2}" =~ ^[0-9]+$ ]]; then
KEEP_NUM="${p2}"
fi
fi
}
parse_args "$@"
echo -e "${gl_zi}>>> 备份 fan-webssh${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_huang}保存目录:${gl_lv}${BACKUP_DIR}${gl_bai}"
echo -e "${gl_huang}保留数量:${gl_lv}${KEEP_NUM}${gl_bai}"
echo -e "${gl_huang}数据目录:${gl_lv}${DATA_DIR}${gl_bai}"
[ -d "${DATA_DIR}" ] || { echo -e "${gl_hong}❌ 数据目录不存在: ${DATA_DIR}${gl_bai}"; exit 1; }
# 文件名精确到秒 YYYY-MM-DD_HH-MM-SS
NOW=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_FILE="${BACKUP_DIR}/FanWebSSH-${NOW}.tar.gz"
mkdir -p "${BACKUP_DIR}"
# 在线备份:不停止服务,避免面板自身被 systemctl stop 连带终止(面板与脚本同属系统服务)
echo -e ""
echo -e "${gl_lan}>>> 执行备份:${BACKUP_FILE}${gl_bai}"
if tar -czf "${BACKUP_FILE}" -C "${DATA_DIR}" .; then
echo -e "${gl_lv}>>> 备份完成:${BACKUP_FILE}${gl_bai}"
else
echo -e "${gl_hong}❌ 备份失败${gl_bai}"
exit 1
fi
cd "${BACKUP_DIR}" || exit 1
# 正则适配新格式:FanWebSSH-YYYY-MM-DD_HH-MM-SS.tar.gz
old_files=$(find . -maxdepth 1 -type f -name "FanWebSSH-*.tar.gz" -printf "%f\n" \
| sed -E 's/^FanWebSSH-([0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2})\.tar\.gz$/\1 &/' \
| sort -k1,1 \
| head -n -${KEEP_NUM} \
| awk '{print $2}')
if [ -n "${old_files}" ];then
echo -e ""
echo -e "${gl_hong}>>> 将删除过期备份文件:${gl_bai}"
echo "${old_files}"
echo "${old_files}" | xargs -I {} rm -f "./{}"
else
echo -e "${gl_lv}>>> 无过期备份需要删除${gl_bai}"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_lv}✔ 备份完成:${BACKUP_FILE}${gl_bai}"
echo -e "${gl_huang}还原命令:bash scripts/fan-webssh_recover.sh${gl_bai}"
创建本地脚本
new_script="new_test.sh"
cat > "$new_script" << 'EOF'
#!/bin/bash
# 粘贴脚本源码
EOF
chmod +x "$new_script" && ./"$new_script" && rm -f "$new_script"