缘由

以前是通过 dotfiles 管理器备份各种 dotfile, 可以将系统快速恢复至理想状态。

随着使用的软件越来越多, 系统的定制程度也越来越高。 加上有的软件配置过于分散,这样做的成本也越来越高。

所以直接备份整个系统是更好的选择。

可用方案

Linux 上备份整个系统的方法有很多, 包括但不限于以下几种。

  • Btrfs Snapshots (仅适用于 Btrfs)
  • LVM Snapshots (仅适用于启用了 LVM 时)
  • tar 打包
  • dd
  • e2image (仅适用于 Ext2/3/4)
  • xfsdump (仅适用于 xfs)
  • Clonezilla
  • SquashFS
  • Rsync

具体使用

以上的方法各有各的好处或不足,我的选择是 Rsync。

一切都得自动化,然后写了个 Shell 来便捷的操作。

#!/bin/bash

#
# 备份 Root 分区的数据
#

# 开始备份
start_Backup() {
    sudo rsync --archive --acls --xattrs --exclude={"/boot/*","/dev/*","/media/*","/mnt/*","/proc/*","/run/*","/sys/*","/tmp/*","/lost+found"} --hard-links --delete --delete-excluded --sparse --numeric-ids --info=progress2 --human-readable "/" "$1"

    # 执行同步
    sync
}

# 判断备份类型
backup_Type() {
    echo -e "周备份还是月备份? [ (w)Weekly / (m)Monthly ]"
    read -r W_or_M
    if [[ "$W_or_M" == w ]]; then
        start_Backup "$HOME/System Backup/Weekly/ROOT"
    elif [[ "$W_or_M" == m ]]; then
        start_Backup "$HOME/System Backup/Monthly/ROOT"
    else
        echo "参数错误"
    fi
}

# 开始执行 backup_Type 函数
backup_Type

拓展阅读

以下是上面使用到的 Rsync 参数的解释。

# 必要的参数
    #--archive                      # -a, 以递归方式传输文件,并保留所有文件属性,等于 -rlptgoD (但不含 -H,-A,-X)
    #--acls                         # -A, 保留 ACL 属性 (implies -p)
    #--xattrs                       # -X, 保留扩展属性
    #--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} # 排除文件与目录
    #--exclude='*~'                 # 排除以 ~ 结尾的文件
    #--exclude-from=root.exclude    # 从 root.exclude 文件中读取额外的排除列表
    #--hard-links                   # -H, 保留硬链接
    #--delete                       #     从 DEST 目录中删除无关文件
    #--delete-excluded              #     还从目录中删除排除的文件
    #--sparse                       # -S, 对稀疏文件进行特殊处理以节省 DST 的空间
    #--numeric-ids                  #     禁用用户名和组名的映射,将转移为数字的组和用户 ID
# 可选项
    #--info=progress2               #     显示整体的进度和传输速度信息
    #--verbose                      # -v, 详细模式输出
    #--progress                     #     转移期间显示进度 
    #--human-readable               # -h, 以人类可读的格式输出数字
    #--inplace                      #     就地更新目标文件
    #--itemize-changes              # -i, 输出所有更新的更改摘要