有没有办法告诉rsync
只同步目标上丢失的源目录(整个目录,而不仅仅是任何丢失的文件)?
考虑S
到源目录集和D
目标目录集,我想:
- 如果不在 中,则将整个目录复制
s
到 中。S
s
D
- 如果在.
s
s
D
当然,可以列出两侧的目录、rsync
来自目标的列表,执行一些操作perl
并生成需要复制的所有目录的列表,但如果只需一次调用rsync
.
例如,如果源和目标位于同一服务器上,则可以执行以下操作:
src=/some/where
dst=/else/where
cd /tmp
(cd $src; find . -type d) | sort > a
(cd $dst; find . -type d) | sort > b
comm -23 a b | perl -e 'L: while(<>) {chomp; $p=$_; while ($p=~s,/[^/]+$,,) { next L if $n{$p}; } $n{$_}++; s,^./,/,; print "$_/***\n"}' > tocopy
rsync -vmazn --include-from tocopy --exclude '*' $src/ $dst/
(没有-n
if 是真的)。
PS:请注意,上面的 perl“一行”(或多或少)删除了我们决定复制的目录的子目录(因为这些子目录包含在其父目录的副本中)。该配方最终得到了要复制的最小目录集。
答案1
无论你想要什么,我都想不出单独使用 rsync 来做到这一点的方法。
如果您确实想完全跳过目标端存在的目录,那么测试不是递归的,只有顶层目录或目录很重要。对于要复制的每个参数 ( in ),要么目录存在于目标端并且无需执行任何操作,要么源目录不存在并且您想要将其整个复制。dirN
rsync --flag-that-you-hope-exists dir1 dir2 dir3 destination/
cd /path/to/source
for x in dir1 dir2 dir3; do
[ -e "/path/to/target/$x" ] || cp -Rp -- "$x" /path/to/target/
done
如果您实际上想递归到目标端存在的目录,并且仅在目录丢失时复制文件,可以使用以下方法find
遍历源目录并检查每个相应的目标目录。
cd /path/to/source
find . -type d -exec sh -c '
if [ -e "$0/$1" ]; then exit 0; fi
cp -Rp -- "$1" "$0/$1"
exit 1
' /path/to/target {} \; -prune
如果源或目标是远程的,则使用以下命令挂载它SSHFS。
答案2
我正在寻找几乎完全相同的问题的解决方案,但我只需要检查第一级目录。即我想从中复制内容srcDir
以跳过已存在的dstDir
目录(不检查其日期、大小或内容)。我很惊讶显然没有办法做到这一点。所以我想出了以下解决方案。srcDir
dstDir
rsync
cd "$srcDir"
for f in *
do
if [[ -d "$f" ]]
then
if [[ ! -d "$dstDir/$f" ]]
then
cp -a "$f" "$dstDir"
fi
fi
done
cd ..