如何写一个自动备份脚本

wen 实用脚本 2

从入门到生产级部署的完整指南

目录导读

  1. 为什么你需要一个自动备份脚本 – 数据丢失的代价与备份策略的核心逻辑
  2. 备份脚本的三种主流实现语言 – Bash / Python / PowerShell 对比与选型
  3. 手写第一个备份脚本 – 文件级备份、压缩、时间戳命名
  4. 数据库与容器化应用的备份技巧 – MySQL/PostgreSQL/Docker Volume 专用方案
  5. 让脚本“自动”起来 – cron、systemd timer、Windows 任务计划程序
  6. 日志、错误处理与告警 – 让你的脚本“会说话”
  7. 备份验证与恢复演练 – 最容易被忽略的关键步骤
  8. 安全加固:加密、权限与远程存储 – 防止备份成为新的风险点
  9. 常见陷阱与 FAQ 问答 – 解决你的高频疑惑

为什么你需要一个自动备份脚本

每次误删文件、勒索病毒加密磁盘或服务器硬盘突然损坏,都是对“没做备份”的惨痛报复,手动复制文件的方式根本不可靠——你总会忘记、拖延,或者在高强度工作下漏掉关键数据。自动备份脚本的价值在于:用机器纪律取代人类惰性,在固定时间点、以固定策略、将关键数据复制到安全位置。

如何写一个自动备份脚本

一个合格备份脚本需要满足的核心原则是 3-2-1 规则:至少三份副本、两种不同存储介质、一份异地备份,脚本的意义正是让这个规则无需人工干预即可执行。

备份脚本的三种主流实现语言

语言 优势 劣势 适用场景
Bash 所有 Linux 自带,文本处理强 跨平台差,日期运算繁琐 标准 Linux 服务器的文件打包
Python 易读、跨平台、库丰富(如 shutilparamiko 需安装解释器 需要复杂逻辑(增量、去重)的备份
PowerShell Windows 原生集成,权限控制细 语法反直觉,Linux 支持有限 Windows Server、Exchange 备份

选型建议:如果你在 Linux 上做简单 tar.gz 打包,Bash 足够;若需要校验完整性、连接云存储或做增量备份,Python 更从容;Windows 环境则优先 PowerShell。

手写第一个备份脚本(Bash 示例)

以下是一个最小可用脚本,备份 /data 目录并保留 7 天:

#!/bin/bash
# 变量定义
BACKUP_DIR="/backups"
SOURCE_DIR="/data"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
FILENAME="backup_${TIMESTAMP}.tar.gz"
# 创建备份
tar -czf "${BACKUP_DIR}/${FILENAME}" "${SOURCE_DIR}"
# 删除7天前的旧备份
find "${BACKUP_DIR}" -name "*.tar.gz" -mtime +7 -delete
# 输出日志
echo "[$(date)] 备份完成: ${FILENAME}" >> /var/log/backup.log

要点说明TIMESTAMP 保证文件名唯一,find -mtime 实现自动清理,这是最基础的骨架——实际使用时你需要根据需求增加更多逻辑。

数据库与容器化应用的备份技巧

MySQL 备份不能直接复制数据文件(容易损坏且不一致),正确方法是使用 mysqldump

mysqldump -u root -p[密码] --all-databases | gzip > /backups/db_$(date +%F).sql.gz

Docker 容器备份则需要利用容器挂载卷或docker cp

docker run --rm --volumes-from my_container -v /backups:/backup ubuntu tar czf /backup/vol_backup.tar.gz /data

增量备份更复杂,推荐使用 rsync(支持差异同步):

rsync -av --delete /source/ /backup/local_mirror/

关键点:数据库备份和文件备份必须分开执行,因为数据库需要一致性快照,而文件级复制会导致表损坏。

让脚本“自动”起来

Linux 使用 cron,编辑 crontab -e

# 每天凌晨2点备份
0 2 * * * /usr/local/bin/backup_script.sh > /dev/null 2>&1

更现代的方式是 systemd timer(更适合需要精确控制启动顺序和依赖的服务):

[Unit]
Description=Daily backup
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target

Windows 使用任务计划程序,或者 schtasks 命令:

schtasks /create /tn "Backup" /tr "C:\scripts\backup.bat" /sc daily /st 02:00

关键细节:cron 环境变量比 shell 少,脚本内务必使用绝对路径,建议在脚本开头加 export PATH=/usr/local/bin:/usr/bin:/bin

日志、错误处理与告警

没有反馈的备份脚本如同石沉大海,至少需做到三点:

  • 错误捕获set -euo pipefail 让脚本在出错时立即退出
  • 日志记录tee 同时输出到屏幕和日志文件
  • 告警通知:失败时发送邮件或钉钉/企业微信 webhook:
if [ $? -ne 0 ]; then
    curl -X POST "https://your-webhook" -d "备份失败于 $(hostname)"
fi

备份验证与恢复演练(务必重视)

备份后不验证 = 没备份,在脚本中加入测试恢复:

# 解压并校验完整性
tar -tzf "${BACKUP_DIR}/${FILENAME}" > /dev/null && echo "压缩包未损坏"
# 核心文件对比
diff <(tar -xzOf "${BACKUP_DIR}/${FILENAME}" "${SOURCE_DIR}/critical.txt") "${SOURCE_DIR}/critical.txt"

每月做一次真实恢复演练,将备份恢复到临时目录并启动服务,这一步能发现 90% 的备份失效问题。

安全加固:加密、权限与远程存储

  • 加密:使用 gpgopenssl 加密备份文件,防止备份被盗后泄露
  • 权限:备份目录设为 0700,避免其他用户读取敏感数据
  • 远程存储:通过 rsync+sshrclone(支持 S3/OSS)将备份传至异地,避免与源数据在同一物理磁盘

常见陷阱与 FAQ 问答

Q1:备份文件比源数据还大怎么办? A:检查是否包含临时文件或缓存目录,用 --exclude 排除,若仍需压缩,考虑启用 zstd 替代 gzip,压缩比更高且速度更快。

Q2:如何备份正在使用的文件(如数据库热备份)? A:对 MySQL 使用 --single-transaction 可保证一致性;对普通日志文件,用 cp --reflink=auto(支持 CoW 的文件系统)避免复制过程中的写入冲突。

Q3:cron 没有执行脚本,可能原因是什么? A:优先检查脚本是否有执行权限(chmod +x),其次查看 /var/log/cron 日志,还有可能是变量 PATH 不包含 targzip 等命令路径。

Q4:备份失败但无告警,如何排查? A:先手动执行脚本看输出,再确认 webhook URL 是否可达,建议将告警逻辑独立于备份主流程,避免主脚本提前退出导致告警代码未运行。

Q5:增量备份和全量备份如何组合? A:典型策略是:每周日全量备份,周一至周六增量备份(使用 rsync --link-dest 创建硬链接全量镜像,既节省空间又保持所有版本)。


自动备份脚本不是一次性写完之后忘掉的工具,而是一个需要持续维护的“数据保险”,从最简的 tar 命令开始,逐步加入错误处理、远程同步、加密验证,最终你会得到一套符合 3-2-1 原则的生产级备份系统。测试、测试、再测试——只有在紧急恢复时真正成功的备份,才叫备份,现在就开始动手写你的第一个脚本吧,半小时后你就摆脱了“裸奔”状态。

上一篇脚本能做什么日常任务

下一篇当前分类已是最新一篇

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