Given: A source directory /mnt1/src
, a destination directory /mnt2/dest
.
Problem: For a daily backup, I want to rsync all files in the tree under /mnt1/src into /mnt2/dest, so that for example /mnt1/src/foo/bar
ends up into /mnt2/dest/foo/bar
. Files below dest
, which have no corresponding entry under src
, should be deleted from dest
.
Environment: zsh
I tried
rsync --delete -ra /mnt1/src/*(D) /mnt2/dest
This nearly works, but has the problem that for instance if I have an extraneous file dummy
inside dest
, which was for instance produced by
touch /mnt2/dest/dummy
, this file would not be removed, because the globbing (src/*(D)
) does not contain this file and rsync therefore ignores it.
Of course I could do a
rsync --delete -ra /mnt1/src /mnt2/dest
and this would remove such extra files, but a file /mnt1/src/foo/bar
would then end up in /mnt2/dest/src/foo/bar
, which I don't want either.
I could do a
mv /mnt2/dest /mnt2/src
rsync --delete -ra /mnt1/src /mnt2
mv /mnt2/src /mnt2/dest
and this would do the job, but it looks unnecessarily complicated to me. Is there a way to accomplish my goal, without renaming directories before and after?
Per the comments, rsync
is particular about whether there is a trailing '/'
following the src
operand. The presence or absence of the '/'
controls whether the "contents-of" or the "directory-itself" is transferred, respectively. For example, in your case if you provide the trailing slash, e.g.
rsync --delete -ra /mnt1/src/ /mnt2/dest
Everything below /mnt1/src
is transferred to /mnt2/dest
.
If you omit the '/'
following src
, the src
directory itself (and everything below it) is transferred, resulting in /mnt2/dest/src/....
(not what you want)
Additionally, you can tweak your options a bit. In -ra
, the -r
is duplicative as -a
implies -rlptgoD
. To insure you only copy new and updated files, add the -u
option. The --delete
option will delete files from dest
not present in src
.
Putting it altogether, you could accomplish what you are attempting with:
rsync -ua --delete /mnt1/src/ /mnt2/dest
If you would like to see what is being transferred, add -v
for verbose output, or I like the -i
summary output. Good luck with your scripting. Let me know if you have questions.