让 rsync 等待确认后再实际更改文件

让 rsync 等待确认后再实际更改文件

我正在同步本地和远程文件夹。结果我因为一个愚蠢的命令丢失了一个文件。

我习惯于一致以及在进行实际文件传输之前确认(“开始?”)的方式。

rsync 有这样的选项吗?(服务器端没有一致)

谢谢!

答案1

rsync 自己的“批处理模式”可以代替官方的“--confirm”选项,从而避免必须两次计算两个路径之间的差异。批处理模式旨在将更改分发到镜像(计算一次,更新许多相同的树)。创建两个文件:一个包含更新的批处理文件和一个用于运行更新的简单便捷脚本(在末尾有一个部分rsync 手册页详细了解)。

下面是用于抽象该过程的 bash 包装器:

#!/bin/bash

cleanup ()
{
    rm ${BFILE} ${BFILE}.sh &>/dev/null
}

# generate tmpfile
BFILE=$( mktemp )

# rsync command
if ! rsync --only-write-batch="${BFILE}" --verbose "$@"; then
    cleanup
    exit 1
fi

# confirmation
read -p "Continue (y/N)? " confirm
if [ "$confirm" != "y" ]; then
    echo "Aborting"
    cleanup
    exit 1
fi

# carve up arguments
dest="${@: -1}"         # last argument
host="${dest%%:*}"      # host:path
path="${dest#*:}"
opts="${@:1:$(($#-2))}" # everything but the last two args
if [ "$host" = "${path}" ]; then
    # local
    sh "${BFILE}.sh"
else
    # remote
    ssh "$host" rsync --read-batch=- "${opts}" "${path}" <"${BFILE}"
fi

cleanup

请注意,由于此脚本写入$TMP_DIR,如果您移动非常大的数据(例如,大于 /tmp),您可能会遇到空间限制。

答案2

您可以使用 rsync 的 -n 选项来执行试运行。rsync 会告诉您它本应执行哪些操作,而无需实际执行这些操作。如果您对结果满意,请在不使用 -n 选项的情况下重新运行。

答案3

您可以使用 --backup 选项让 rsync 在覆盖时备份文件,

 -b, --backup                make backups (see --suffix & --backup-dir)
     --backup-dir=DIR        make backups into hierarchy based in DIR
     --suffix=SUFFIX         backup suffix (default ~ w/o --backup-dir)

rsync 运行后,您可以扫描备份目录中的文件并逐个询问是否需要恢复。

答案4

遗憾的是,在撰写本文时,Rsync 中没有内置方法。

Mike Fitzpatrick 的解决方案效果很好,但是如果你有一个非常大的目录树,你可能需要做一些事情,让 rsync 不再重复遍历所有文件

编辑:还有一个错误,它不会删除目标文件...我越看越觉得这个解决方案有问题...我保留它,因为它可能适用于你的情况,而且如果有人想修复它。另外,有人应该向提交正式的功能请求https://bugzilla.samba.org/enter_bug.cgi?product=rsync

我写了这个脚本:

#! /bin/bash

# Make a temp file for storing the output of rsync

tmpfile=$( mktemp )  &&

# Do all the hard work ( get the list of files we need to update ), 
#  but dont actually change the filesystem

rsync --dry-run --out-format='RSYNC_CONFIRM %i %n%L' "$@" | grep RSYNC_CONFIRM | awk '{ print $3 }' > $tmpfile &&


# Output to the user what we propose to do
rsync --dry-run --itemize-changes --files-from=$tmpfile "$@" &&

# Alternatively, we could just output $tmpfile... but whatever...

read -p "Continue? (y/n)?" &&

if [[ $REPLY = [yY] ]]
then
{
  rsync --files-from=$tmpfile "$@"
}
fi

rm $tmpfile
  • 尝试将脚本粘贴到名为rsync-confirm.bash

  • 然后chmod +x rsync-confirm.bash

  • 然后./rsync-confirm.bash -rvh /etc/ /tmp/etc/

这个脚本可能有点小问题,我注意到如果源目录上没有尾随斜杠的话它就不太喜欢它了...

相关内容