工具效率

安全 Shell 自动化:编写可校验、可恢复的目录备份脚本

从严格模式、路径校验、临时文件和校验和入手,编写一份失败不留半成品、恢复前可验证的 Bash 备份脚本。

TY
Tycho
技术博主
• 2026-09-23 • 11 分钟阅读 • 9 次浏览
安全 Shell 自动化:编写可校验、可恢复的目录备份脚本

自动化脚本的价值不只是“能跑”,而是输入错误时拒绝执行、失败时不留下伪成功文件、恢复时能证明备份没有损坏。下面从一个目录备份需求开始。

一、明确输入、输出和安全边界

  • 源目录必须存在,且不能是 /。
  • 目标目录由脚本创建。
  • 先写临时文件,成功后原子移动为最终文件。
  • 生成 SHA-256 校验文件,并做一次测试恢复。

二、编写脚本骨架

#!/usr/bin/env bash
set -Eeuo pipefail
IFS=$'\n\t'

usage() {
  echo "Usage: $0 SOURCE_DIR BACKUP_DIR" >&2
  exit 64
}

[[ $# -eq 2 ]] || usage
source_dir=$1
backup_dir=$2

[[ -d "$source_dir" ]] || { echo "Source directory not found" >&2; exit 66; }
[[ "$source_dir" != "/" ]] || { echo "Refusing to back up /" >&2; exit 64; }

mkdir -p -- "$backup_dir"

-e 遇到未处理失败时退出,-u 拒绝未定义变量,pipefail 让管道中任一命令失败都能被发现。变量展开始终加双引号,并在路径参数前使用 --。

三、用临时文件避免半成品

timestamp=$(date -u +%Y%m%dT%H%M%SZ)
archive="$backup_dir/backup-$timestamp.tar.gz"
tmp_archive=$(mktemp "$backup_dir/.backup.XXXXXX")
restore_dir=$(mktemp -d)

cleanup() {
  rm -f -- "$tmp_archive"
  rm -rf -- "$restore_dir"
}
trap cleanup EXIT

tar -C "$(dirname "$source_dir")" \
  -czf "$tmp_archive" \
  "$(basename "$source_dir")"

tar -tzf "$tmp_archive" >/dev/null
mv -- "$tmp_archive" "$archive"

临时文件和最终文件位于同一目录,mv 在同一文件系统内通常可原子完成。只有 tar 创建成功且列表校验通过,最终文件名才会出现。

四、生成校验和并执行恢复测试

sha256sum "$archive" > "$archive.sha256"
sha256sum --check "$archive.sha256"

tar -xzf "$archive" -C "$restore_dir"
test -d "$restore_dir/$(basename "$source_dir")"

printf 'Backup verified: %s\n' "$archive"

macOS 默认可用 shasum -a 256 替代 GNU sha256sum。团队应统一命令并把运行平台写入文档。

五、先做静态检查,再做破坏性测试

bash -n backup.sh
chmod +x backup.sh

mkdir -p /tmp/backup-demo/source
printf 'important\n' > /tmp/backup-demo/source/note.txt
./backup.sh /tmp/backup-demo/source /tmp/backup-demo/output
ls -lh /tmp/backup-demo/output

验收不止看退出码:解压备份,使用 diff -r 比较源目录与恢复目录。再测试不存在的源目录、带空格路径和目标目录不可写等失败场景。

六、恢复流程

sha256sum --check backup-20260101T000000Z.tar.gz.sha256
mkdir -p restore-test
tar -xzf backup-20260101T000000Z.tar.gz -C restore-test
find restore-test -maxdepth 2 -type f -print

先恢复到新目录进行检查,确认所有权、权限和内容正确后,再按业务流程切换。不要直接把归档解压覆盖生产目录。

上线前检查清单

  • 脚本使用专用低权限账户。
  • 备份目录不与源目录互相包含。
  • 日志明确记录开始、成功、失败和归档路径。
  • 磁盘空间、保留周期和异地副本有监控。
  • 定期执行真实恢复演练;“备份成功”不等于“能够恢复”。

官方资料

TY

Tycho

热爱分享技术知识,帮助开发者成长。

评论 (0)

评论功能当前已关闭
暂无评论,快来抢沙发吧!