Cannot get rsync exclude option to exclude dir
mkdir -p test/a/b/c/d/e
mkdir -p test/dest
rsync -nvraL test/a test/dest --exclude=a/b/c/d
This works. As test/a
is the base directory synced from, the exclude pattern is specified by starting with a/
Show us the real paths/excludes if this doesn't help.
Running rsync with -vn will list dirs/files - the pattern is matched against the format that rsync prints.
Either of these would work:
rsync -nvraL test/a test/dest --exclude=/a/b/c/d
rsync -nvraL test/a/ test/dest --exclude=/b/c/d
Note the ending /
in source path makes a critical difference to how --exclude
should be specified. This assumes we have:
mkdir -p test/a/b/c/d/e
mkdir -p test/a/other/place/a/b/c/d
mkdir -p test/dest
Original Post has difficulty when exclude path starts with a /
. Daniel’s answer is correct that this initial /
in exclude path might be desirable to exclude a specific path, and that this initial /
should be understood like leading ^
in regular expressions. However, his answer has a critical typo about the ending /
in source path.
Following Erik's example you want to do this:
rsync -nvraL test/a/ test/dest --exclude=/b/c/d
Actually, neither Erik's nor Antoni's answer is fully accurate.
Erik is halfway right in saying that
As test/a is the base directory synced from, the exclude pattern is specified by starting with a/
It is true that the exclude pattern's root is test/a
(i.e. the pattern /some/path
binds to test/a/some/path
), but that's not the whole story.
From the man page:
if the pattern starts with a / then it is anchored to a particular spot in the hierarchy of files, otherwise it is matched against the end of the pathname. This is similar to a leading ^ in regular expressions. Thus "/foo" would match a file named "foo" at either the "root of the transfer" (for a global rule) or in the merge-file's directory (for a per-directory rule).
We can ignore the per-directory
bit as it doesn't apply to us here.
Therefore, rsync -nvraL test/a test/dest --exclude=a/b/c/d
will most definitely exclude test/a/b/c/d
(and children), but it'll also exclude test/a/other/place/a/b/c/d
.
rsync -nvraL test/a test/dest --exclude=/b/c/d
, on the other hand, will exclude only test/a/b/c/d
(and children) (test/a
being the point to which /
is anchored).
This is why you still need the anchoring inital slash if you want to exclude that specific path from being backed up. This might seem like a minor detail, and it will be so the more specific your exclude pattern becomes (e.g. Pictures
vs. home/daniel/Pictures
) but it might just come around to bite you in the butt.