How can I prevent a directory from being removed in rsync How can I prevent a directory from being removed in rsync shell shell

How can I prevent a directory from being removed in rsync


Rsync is an awesome tool, but sometimes difficult to use.

The problem is you're using --exclude-from, which sets global exclude rules to both the sending and receiving side.

Before rsync performs operations on the filesystem, it will first assemble two lists of files, one for the sending side (client) and other for the receiving side (server). If a file is excluded from both sides, rsync will simply ignore it. If it is excluded only from the sending side and exists on the receiving side, rsync will delete it.

In your case, since your rules are excluding files from both sides, rsync will not delete them. You then use --delete-excluded to force deletion. But, like you said, this option conflicts with --backup --backup-dir=rsync/backup.

I suggest you do the following.

  1. Convert $EXCL_FROM to a normal filter file, i.e., insert the minus sign before each line to make them exclude rules.
  2. Remove --exclude-from=$EXCL_FROM and --delete-excluded from the rsync options.
  3. Include -FF on the rsync options.
  4. Include the following command before the call to rsync.

    cp "$EXCL_FROM" "$SRC/.rsync-filter"

In this way, your rules will only apply to the sending side, and files specified as exclude rules will be removed from the receiving side if found. This should not conflict with backup options.

Update

Essentially, the -FF option is making rsync process per-directory filter files named .rysnc-filter in both sides of the transfer. In your case it will exist only on the sending side, so its rules won't apply to the receiving side.

Actually, -FF equals to -F -F. The first F tells rsync to merge rules from .rsync-filter in the root of the source and destination directories, like I said before. The second F tells rsync to exclude them. You don't want .rsync-filter being transferred, otherwise your exclude rules would also apply to the receiving side and your original problem would return – the excluded files would cease to be deleted.

Here's what my man (1) rsync says:

-F    same as --filter='dir-merge /.rsync-filter'      repeated: --filter='- .rsync-filter'


One alternative is to locate your --backup-dir outside of your backup folder using absolute paths (specified with ../).

ie. --backup-dir="../rsync/backup/${DATE}"

This will create a new folder at the same level as your destination folder. For example, if you were exporting to /home/user/rsync/backup the above command would store your deleted files at home/user/rsync/rsync/backup/${DATE}