实用脚本能批量备份吗?

wen 实用脚本 9

本文目录导读:

实用脚本能批量备份吗?

  1. 批量备份多个目录/文件(本地)
  2. 批量备份 MySQL/MariaDB 所有数据库
  3. 批量备份远程服务器(Rsync + SSH)
  4. 可视化/菜单式批量备份(结合 select
  5. 如何让脚本批量备份变得“更实用”?

可以的,实用脚本完全可以批量备份,而且这正是脚本最擅长的场景之一。

批量备份的核心逻辑就是:循环 + 备份指令,将需要备份的文件列表、数据库列表或服务器列表写在一个配置文件里,然后由脚本逐行读取并执行备份操作。

下面我为你提供几个可直接使用的实用批量备份脚本示例,涵盖文件、数据库和远程服务器备份。

批量备份多个目录/文件(本地)

这个脚本会读取一个 backup_list.txt 文件,该文件中每行是一个待备份的路径,然后将它们打包成一个带时间戳的压缩包。

脚本:batch_backup.sh

#!/bin/bash
# --- 配置区域 ---
BACKUP_DIR="/path/to/your/backup/folder"  # 备份文件存放的目录
LIST_FILE="/path/to/backup_list.txt"       # 待备份目录列表文件
DATE=$(date +%Y%m%d_%H%M%S)                # 时间戳
# --- 检测文件夹是否存在,不存在则创建 ---
mkdir -p "$BACKUP_DIR"
# --- 日志输出 ---
echo "开始批量备份,时间:$DATE"
echo "备份列表文件:$LIST_FILE"
# --- 核心:逐行读取并打包 ---
while IFS= read -r path; do
    # 跳过空行和注释行(以#开头)
    [[ -z "$path" || "$path" == \#* ]] && continue
    # 检查源路径是否存在
    if [ -e "$path" ]; then
        # 将路径中的 "/" 替换为 "_",用于生成文件名
        safe_name=$(echo "$path" | sed 's|/|_|g' | sed 's|^_||')
        archive_name="${BACKUP_DIR}/${safe_name}_${DATE}.tar.gz"
        echo "正在备份: $path -> $archive_name"
        # 执行打包压缩(排除 .git node_modules 等大型目录)
        tar -czf "$archive_name" \
            --exclude=".git" \
            --exclude="node_modules" \
            --exclude="vendor" \
            "$path"
        # 检查备份是否成功
        if [ $? -eq 0 ]; then
            echo "✅ 备份成功: $archive_name"
        else
            echo "❌ 备份失败: $path"
        fi
    else
        echo "⚠️  路径不存在: $path"
    fi
done < "$LIST_FILE"
echo "批量备份完成!"

配置文件:backup_list.txt(放在脚本同目录下)

# 这是注释,不会被执行
/home/user/projects
/etc/nginx
/var/www/html
# /tmp/test  # 注释掉的路径会被跳过
/opt/data

使用方法:

  1. 创建上述两个文件。
  2. 修改 BACKUP_DIRLIST_FILE 路径。
  3. 运行:chmod +x batch_backup.sh && ./batch_backup.sh

批量备份 MySQL/MariaDB 所有数据库

此脚本会连接 MySQL,获取所有数据库列表(排除系统库),然后逐个备份为 .sql.gz 文件。

脚本:mysql_batch_backup.sh

#!/bin/bash
# --- 配置 ---
BACKUP_DIR="/backup/mysql"
DB_USER="root"
DB_PASSWORD="your_password"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
echo "开始 MySQL 批量备份..."
# 获取所有数据库(排除系统库)
databases=$(mysql -u $DB_USER -p$DB_PASSWORD -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql|sys)")
for db in $databases; do
    backup_file="${BACKUP_DIR}/${db}_${DATE}.sql.gz"
    echo "备份数据库: $db -> $backup_file"
    # 使用 mysqldump 备份并压缩
    mysqldump -u $DB_USER -p$DB_PASSWORD "$db" | gzip > "$backup_file"
    if [ $? -eq 0 ]; then
        echo "✅ 备份成功: $backup_file"
        # 可选:只保留最近7天的备份
        find "$BACKUP_DIR" -name "${db}_*.sql.gz" -mtime +7 -delete
    else
        echo "❌ 备份失败: $db"
    fi
done
echo "数据库批量备份完成!"

使用提示:

  • 生产环境建议使用 .my.cnf 配置文件管理密码,而不是直接在脚本中写明文密码。
  • 脚本末尾的 find ... -delete 实现了自动清理7天前的旧备份。

批量备份远程服务器(Rsync + SSH)

如果你需要将多台服务器上的指定目录备份到本机(或备份服务器),可以使用这个脚本。

脚本:remote_batch_backup.sh

#!/bin/bash
# --- 配置 ---
BACKUP_BASE_DIR="/backup/remote"
LOCAL_DATE=$(date +%Y%m%d)
# 服务器列表文件:格式为 user@hostname:/path/on/remote
SERVER_LIST="/path/to/server_list.txt"
mkdir -p "$BACKUP_BASE_DIR"
echo "开始远程服务器批量备份 (Rsync)..."
echo "使用服务器列表: $SERVER_LIST"
while IFS= read -r entry; do
    # 跳过空行和注释
    [[ -z "$entry" || "$entry" == \#* ]] && continue
    # 解析用户和远程路径
    host_user=$(echo "$entry" | cut -d: -f1)
    remote_path=$(echo "$entry" | cut -d: -f2-)
    # 提取主机名作为备份子目录名
    hostname=$(echo "$host_user" | cut -d@ -f2)
    backup_dest="${BACKUP_BASE_DIR}/${hostname}${remote_path}_${LOCAL_DATE}"
    echo "正在备份: $host_user:$remote_path -> $backup_dest"
    # 使用 rsync 进行增量/全量备份
    # --archive 保留权限、时间戳等
    # --partial 断点续传
    # --delete 删除目标端没有的源文件(谨慎使用)
    rsync -avz --partial \
        -e "ssh -o StrictHostKeyChecking=no -i /path/to/ssh_key" \
        "$host_user:$remote_path" \
        "$backup_dest"
    if [ $? -eq 0 ]; then
        echo "✅ 远程备份成功: $hostname"
        # 创建指向最新备份的软链接
        ln -snf "$backup_dest" "${BACKUP_BASE_DIR}/${hostname}${remote_path}_latest"
    else
        echo "❌ 远程备份失败: $hostname"
    fi
done < "$SERVER_LIST"
echo "远程批量备份完成!"

配置文件:server_list.txt

# 格式:user@hostname:/remote/path
root@192.168.1.10:/var/www
admin@backup-server:/data/projects
# ops@db1:/etc/mysql   # 注释掉
user@app2:/home/user/logs

使用提示:

  • 需要提前配置好 SSH 密钥对(无密码登录),脚本中使用了 -i /path/to/ssh_key 指定私钥。
  • --delete 参数会删除目标端已有的但源端不存在的文件,如果你只想单向复制,可以去掉这个参数。

可视化/菜单式批量备份(结合 select

如果你希望有一个交互式选择界面,可以这样做:

#!/bin/bash
# 定义备份任务函数
backup_project_a() {
    echo "备份 Project A..."
    tar -czf /backup/project_a_$(date +%Y%m%d).tar.gz /home/user/project_a
}
backup_project_b() {
    echo "备份 Project B..."
    mysqldump -u root -p project_b | gzip > /backup/project_b_$(date +%Y%m%d).sql.gz
}
backup_all() {
    echo "执行全部备份..."
    backup_project_a
    backup_project_b
    # 可以追加更多任务
}
# 交互菜单
echo "请选择要执行的备份任务:"
select action in "备份所有项目" "备份 Project A" "备份 Project B" "退出"
do
    case $action in
        "备份所有项目") backup_all;;
        "备份 Project A") backup_project_a;;
        "备份 Project B") backup_project_b;;
        "退出") break;;
        *) echo "无效选择";;
    esac
done

如何让脚本批量备份变得“更实用”?

  1. 定时自动执行(最重要的功能)

    • 使用 crontab 将其设为定时任务。
    • 例如每天凌晨 3 点运行:0 3 * * * /path/to/batch_backup.sh
  2. 备份完成后发送通知

    • 可以在脚本尾部添加:
      if [ $? -eq 0 ]; then
          mail -s "批量备份成功" admin@example.com < /dev/null
          # 或发送到钉钉/微信机器人
          curl -X POST -H "Content-Type: application/json" -d '{"msgtype":"text","text":{"content":"备份完成"}}' https://oapi.dingtalk.com/robot/send?access_token=xxx
      fi
  3. 错误日志与重试机制

    • 将失败的任务记录到日志文件 /var/log/backup_error.log
    • 使用 for 循环配合 retry 计数,失败时重试 3 次。
  4. 增量备份优化

    • 对于大文件或数据库,使用 rsyncxtrabackup 实现增量备份,而非每次都全量打包。

是的,脚本非常适合批量备份。 你只需要:

  • 准备好要备份的资源列表(文件路径、数据库名、服务器地址)。
  • 用一个循环逐个执行打包或 mysqldump 命令。
  • 加上时间戳、自动清理、通知提醒等辅助功能。

如果你有具体的备份需求(比如备份 Docker 容器、Kubernetes 资源或特定应用数据),可以告诉我,我帮你定制一个更精确的脚本。

抱歉,评论功能暂时关闭!