随机
Enter 搜索 ↑↓ 切换 Esc 清空

fan-files_backup

命令

fan-files 备份数据

一键脚本

bash <(curl -sL https://raw.githubusercontent.com/meimolihan/fan-files/main/scripts/fan-files_backup.sh) 6
用法 命令 说明
使用默认 ./fan-files_backup.sh 备份到默认目录,保留 6 份
只传保留份数 ./fan-files_backup.sh 10 自定义保留 10 份
只传备份目录 ./fan-files_backup.sh /data/bak 自定义备份目录,保留 6 份
目录 + 保留数 ./fan-files_backup.sh /data/bak 8 自定义目录与保留数量
顺序互换 ./fan-files_backup.sh 8 /data/bak 保留数在前,顺序兼容

补充说明

该脚本用于 fan-files 服务数据一键备份,流程为:读取 /etc/fan-files.conf 安装记录得到数据目录 → 停止 fan-files systemd 服务 → tar 打包数据目录生成备份文件(文件名精确到秒,自动排除备份目录自身)→ 按保留数量自动清理过期备份 → 重新启动服务并校验状态。

功能特点

输出说明

脚本输出包含以下内容:

字段 说明
保存目录 备份文件存放路径
保留数量 设置的保留备份份数(默认 6)
数据目录 安装记录中读取的数据目录路径
执行备份 正在生成的备份文件完整路径
删除列表 将要删除的过期备份文件列表
服务状态 重启后 fan-files 服务运行状态(运行中/已停止/启动失败)

注意事项

定时任务示例

# 下载脚本到系统目录
curl -fsSL https://raw.githubusercontent.com/meimolihan/fan-files/main/scripts/fan-files_backup.sh -o /usr/local/bin/fan-files_backup

# 增加执行权限
chmod +x /usr/local/bin/fan-files_backup

# 追加定时任务(防重复追加)
(crontab -l 2>/dev/null | grep -Fq '/usr/local/bin/fan-files_backup 6') || (crontab -l 2>/dev/null; echo '30 2 * * * /usr/local/bin/fan-files_backup 6 >> /var/log/fan-files_backup.log 2>&1') | crontab -

# 查看日志
cat /var/log/fan-files_backup.log

脚本源码

#!/bin/bash
set -uo pipefail

gl_hui='\033[38;5;59m'
gl_hong='\033[38;5;9m'
gl_lv='\033[38;5;10m'
gl_huang='\033[38;5;11m'
gl_lan='\033[38;5;32m'
gl_bai='\033[38;5;15m'
gl_zi='\033[38;5;13m'
gl_bufan='\033[38;5;14m'

# 默认值
KEEP_NUM=6
SERVICE="fan-files"
CONFIG_FILE="/etc/fan-files.conf"
DATA_DIR="/var/lib/fan-files"
BACKUP_DIR=""

# 从安装记录读取数据目录(不存在时使用默认值)
if [ -f "${CONFIG_FILE}" ]; then
  while IFS='=' read -r KEY VALUE; do
    KEY=$(printf '%s' "$KEY" | tr -d ' ')
    [ "$KEY" = "DATA_DIR" ] && [ -n "$VALUE" ] && DATA_DIR="${VALUE}"
  done < "${CONFIG_FILE}"
fi

# 默认备份目录:数据目录下的 backup 子目录
[ -z "${BACKUP_DIR}" ] && BACKUP_DIR="${DATA_DIR}/backup"

# 参数解析,支持两种传参顺序可互换
# ./fan-files_backup.sh                     # 使用默认
# ./fan-files_backup.sh 10                  # 只传保留份数
# ./fan-files_backup.sh /data/bak           # 只传备份目录
# ./fan-files_backup.sh /data/bak 8         # 目录 保留数
# ./fan-files_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-files${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}"

command -v systemctl >/dev/null 2>&1 || { echo -e "${gl_hong}❌ 未检测到 systemctl,无法备份服务${gl_bai}"; exit 1; }

[ -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}/FanFiles-${NOW}.tar.gz"

mkdir -p "${BACKUP_DIR}"

echo -e ""
echo -e "${gl_huang}>>> 停止 ${SERVICE} 服务${gl_bai}"
systemctl stop ${SERVICE}

echo -e ""
echo -e "${gl_lan}>>> 执行备份:${BACKUP_FILE}${gl_bai}"
# 排除备份目录本身,避免 "file changed as we read it" 错误
BACKUP_REL="${BACKUP_DIR#${DATA_DIR}/}"
if tar -czf "${BACKUP_FILE}" -C "${DATA_DIR}" --exclude="${BACKUP_REL}" .; then
    echo -e "${gl_lv}>>> 备份完成:${BACKUP_FILE}${gl_bai}"
else
    echo -e "${gl_hong}❌ 备份失败,正在恢复服务${gl_bai}"
    systemctl start ${SERVICE}
    exit 1
fi

cd "${BACKUP_DIR}" || exit 1

# 正则适配新格式:FanFiles-YYYY-MM-DD_HH-MM-SS.tar.gz
old_files=$(find . -maxdepth 1 -type f -name "FanFiles-*.tar.gz" -printf "%f\n" \
| sed -E 's/^FanFiles-([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 ""
echo -e "${gl_huang}>>> 启动 ${SERVICE} 服务${gl_bai}"
systemctl start ${SERVICE}

sleep 2
STATUS=$(systemctl is-active ${SERVICE})
case "${STATUS}" in
    active)
        echo -e "${gl_lv}✅ 服务状态:运行中${gl_bai}"
        ;;
    inactive)
        echo -e "${gl_hong}❌ 服务状态:已停止${gl_bai}"
        ;;
    failed)
        echo -e "${gl_hong}❌ 服务状态:启动失败${gl_bai}"
        ;;
    *)
        echo -e "${gl_huang}⚠️ 服务状态:${STATUS}${gl_bai}"
        ;;
esac
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

创建本地脚本

new_script="new_test.sh"

cat > "$new_script" << 'EOF'
#!/bin/bash

# 粘贴脚本源码

EOF

chmod +x "$new_script" && ./"$new_script" && rm -f "$new_script"

相关命令