rsync 脚本如何删除我的 NAS 上的大部分文件?

rsync 脚本如何删除我的 NAS 上的大部分文件?

所以我正在关注本教程备份我的 Debian 实例

运行脚本后,我注意到它被设置为仅备份主目录。我想将根目录中的所有内容备份到 NAS 中的目录。所以我修改了脚本,如下所示:

#!/bin/bash

# A script to perform incremental backups using rsync

set -o errexit
set -o nounset
set -o pipefail

readonly SOURCE_DIR="/"
readonly BACKUP_DIR="/link/to/my/nas/Server Backups"
readonly DATETIME="$(date '+%Y-%m-%d_%H:%M:%S')"
readonly BACKUP_PATH="${BACKUP_DIR}/${DATETIME}"
readonly EXCLUDE="/link/to/my/nas/
readonly LATEST_LINK="${BACKUP_DIR}/latest"

mkdir -p "${BACKUP_DIR}"

rsync -av --delete \
  "${SOURCE_DIR}/" \
  --link-dest "${LATEST_LINK}" \
  --exclude=".cache" \
  "${BACKUP_PATH}" \
  "${EXCLUDE}"

rm -rf "${LATEST_LINK}"
ln -s "${BACKUP_PATH}" "${LATEST_LINK}"

它删除了我 NAS 上的几乎所有内容!我假设没有办法撤消这一点。这并不是世界末日,因为它是有备份的。但这里到底发生了什么???为什么它没有按预期备份以及为什么它删除了除 LATEST_LINK 下的文件之外的任何内容?

运行脚本的日志:

root:/utils# ./backup-script.sh
sending incremental file list
rsync: [sender] link_stat "/link/to/my/nas/Server Backups/2023-01-07_15:58:36" failed: No such file or directory (2)
--link-dest arg does not exist: /link/to/my/nas/Server Backups/latest
^Crsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(713) [sender=3.2.7]
rsync error: received SIGUSR1 (code 19) at main.c(1613) [generator=3.2.7]

答案1

让我们尝试解释一下为什么 rsync 做了一些你意想不到的事情。

这是您的命令重写为规范顺序,以便命令选项在前面,路径在末尾。这不会改变含义,但有助于解释效果:

rsync
  -av                           # Archive mode, verbosely 
  --delete                      # Delete in destination if not in source
  --link-dest "$LATEST_LINK"    # Link unchanged files to a match by name
  --exclude ".cache"            # Exclude file/directory
  "$SOURCE_DIR/"                # Source 1
  "$BACKUP_PATH"                # Source 2
  "$EXCLUDE"                    # Destination 

显然你的意思是写--exclude "${EXCLUDE}"而不是仅仅"${EXCLUDE}"。不幸的是,您所编写和执行的内容的效果是删除或$EXCLUDE下不存在的所有内容。$SOURCE_DIR$BACKUP_PATH

这是正确编写的命令:

rsync                        \
  -av                        \
  --delete                   \
  --link-dest "$LATEST_LINK" \
  --exclude ".cache"         \
  --exclude "$EXCLUDE"       \
  "$SOURCE_DIR/"             \
  "$BACKUP_PATH"

它现在没有帮助,但为了将来参考,如果您要应用或执行其他一些不可挽回的操作,则--dry-run( ) 标志非常值得使用。我经常用它!-n--delete

相关内容