使rsync在实际更改文件之前等待确认


11

我正在本地和远程文件夹之间进行同步。碰巧我通过一个愚蠢的命令丢失了一个文件。

在习惯进行实际文件传输之前,我习惯于统一并使用您确认的方式(“执行?”)。

rsync有这样的选择吗?(服务器端无协调)

谢谢!

Answers:


3

代替正式的“-确认”选项,可以利用rsync自己的“批处理模式”来绕过必须两次计算两条路径之间的差的情况。批处理模式旨在将更改分发到镜像(计算一次,更新许多相同的树)。创建了两个文件:一个包含更新的批处理文件和一个用于运行更新的简单便捷脚本(在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大),可能会遇到空间限制。


1
这是否要求对每个文件进行确认?
高度不规则的2015年

2
不,这将计算更改,显示更改,然后显示一个提示,“继续(y / N)?”。自从我使用它已经有一段时间了,但是IIRC,rsync似乎仍在重新计算rdiff。
史蒂夫(Steve)

7

可以将-n选项与rsync一起使用以执行试运行。rsync会告诉您将执行哪些操作而无需实际执行。如果对结果感到满意,请在不使用-n选项的情况下重新运行。


7

您可以使用--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后,您可以扫描backup-dir中的文件,并一一询问是否需要还原。


5

可悲的是,在编写本文时,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/

这个脚本可能有点bug,我注意到,如果您在源目录中没有结尾的斜杠,那么它并不是很喜欢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.