Rsync backups: excluding directories

Q I've been trying to set up an rsync script to back up the important contents of my home directory to a USB drive, and I'm having great difficulty whipping it into shape. Particularly confusing is how to use --exclude-from and (even more confusing) --include-from. I'm on an Ubuntu 6.06 system, with rsync 2.6.6. Here's an outline of what I want to happen. First, all of the non-hidden files, directories and their subdirectories etc in my home directory /home/dcoldric are to be backed up, except that for the directory /home/dcoldric/MyDownloads, I don't want any subdirectories to be included, just non-directory files. Another exception is that there is a very limited number of non-hidden subdirectories - such as /home/dcoldric/cxoffice/ - that I do not want to back up. All of the hidden files and directories are to be ignored, except for a few. For example, I do want to back up /home/dcoldric/.netbeans and subdirectories, as well as .bashrc and .bash_aliases. Finally, I'd like the directory structure of the backup to mimic that of the original (except for the ignored directories). I have tried just about everything I can think of, to no avail. My latest variant looks like:

rsync -a --delete --safe-links --exclude-from=/home/dcoldric/bin/backupExcludes
/home/dcoldric/ /media/USB/backup/dcoldric

where the backupExcludes file currently looks like this:

- /*
+ /dcoldric/
+ /dcoldric/.Creator/
+ /dcoldric/.java/
+ /dcoldric/.mozilla/
+ /dcoldric/.mozilla-thunderbird/
+ /dcoldric/.netbeans/
+ /dcoldric/.bashrc
+ /dcoldric/.bash_aliases
+ /dcoldric/MyDownloads/
- /dcoldric/MyDownloads/*/
- /dcoldric/.*
- /dcoldric/cxoffice
- /dcoldric/jdk*
- /dcoldric/sun
- /dcoldric/SUNW*

However, it appears to do nothing.

A The rsync command copies everything by default, so the --exclude option tells it what to skip. It may be clearer to think of --include as --do-not-exclude. The exclude-from file you have given is actually a filter file. Filtering provides control, but it does not have a --filter- from variant. The more correct way to use a filter file is with the option

--filter="merge myfilterfile"

Your current filter file does not work because it starts with - /*, which excludes everything. So when you say it does nothing, you and the program are quite correct - because that is just what you told it to do. The first match counts, so move - /* to the end. When a filter path starts with a /, it is matched relative to the source directory, which is ~/dcoldric. So you need to remove /dcoldric from the start of each path, otherwise you are trying to match /home/dcoldric/dcoldric/.mozilla and so on. Although it doesn't affect your current filters, you should be aware that

+ /foo/bar/
- /*

will match nothing. Because /* excludes everything in the base directory, the contents of foo are never checked, so foo/bar is not found. You need to force rsync to scan foo with

+ /foo/
+ /foo/bar/
- /foo/*
- /*

A working filter file would be

+ /.netbeans/
+ /.bashrc
+ /.bash_aliases
- /MyDownloads/*/
- /.*
- /cxoffice
- /jdk*

Call this with

rsync -a --delete --safe-links --filter="merge~dcoldric/bin/backupFilter"
~dcoldric/ /media/USB/backup/dcoldric/

Note the trailing / on the destination: this can affect the result.

Follow us on or Twitter

Username:   Password:
Create Account | About TuxRadar