rsync exclude directory not working
Global rsync
filter rules beginning with a leading /
are anchored to the root of transfer. Quoting from the "INCLUDE/EXCLUDE PATTERN RULES" section of 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 name of "foo" at either the "root of the transfer" (for a global rule) or in the merge-file's directory (for a per-directory rule).
In your command (rsync ... -arv /home/ben home-ben/
), the file /home/ben/foo
would be transferred to home-ben/ben/foo
. The root of transfer is home-ben
and the correct filter path is /ben/foo
. Thus,
- to match
/home/ben/.ccache
you need a filter path of/ben/.ccache
- to match
/home/ben/build/
you need a filter path of/ben/build/
A more detailed explanation can be found in the "ANCHORING INCLUDE/EXCLUDE PATTERNS" section of the rsync(1)
man page.
Note that simply leaving out the leading /
is not necessarily what you want. Quoting again from the same man page section:
An unqualified "foo" would match a name of "foo" anywhere in the tree because the algorithm is applied recursively from the top down; it behaves as if each path component gets a turn at being the end of the filename. Even the unanchored "sub/foo" would match at any point in the hierarchy where a "foo" was found within a directory named "sub". See the section on ANCHORING INCLUDE/EXCLUDE PATTERNS for a full discussion of how to specify a pattern that matches at the root of the transfer.
Thus a filter pattern of build/
would match a build directory anywhere in /home/ben
, even /home/ben/many/sub/directories/build/
.
WARNING: Per @rubo77's comment below, this answer should only be used if you're willing to exclude these items everywhere in your source tree, not just at the root. See @jw013's answer above for a more thorough explanation.
I think your exclude
paths need to be relative to the source path. Can you try this instead?
rsync --exclude=build/ --exclude=.ccache -arv /home/ben home-ben/
Here's a test, for comparison:
/tmp$ tree src dest
src
├── a
└── b
dest
└── foo/
/tmp$ rsync -nav --exclude /tmp/src/b /tmp/src /tmp/dest
sending incremental file list
src/
src/a
src/b
$ rsync -nav --exclude b /tmp/src /tmp/dest
sending incremental file list
src/
src/a
Your exclude pattern would work, if you rsync the whole /home path i.e. without a trailing slash:
rsync --exclude=/home/ben/build/ --exclude=/home/ben/.ccache -arv /home home-all/
But better only rsync the content of the folder with a trailing slash:
rsync --exclude=/build --exclude=/.ccache -arv /home/ben/ home-ben/
You can use an ignore-list too, see: https://askubuntu.com/questions/545655/backup-your-home-directory-with-rsync-and-skip-useless-folders