Rsync --delete option doesn't delete files in target directory

I'm trying to use the --delete option in rsync to delete files in the target directory which isn't present in the original directory

Here is the command I'm using:

rsync -avz --ignore-existing --recursive --delete /var/www/* [email protected]:/var/www

So my question is, how can I delete all files in target directory which aren't present in the original directory?


Solution 1:

Use this command:

rsync --archive --verbose --compress --ignore-existing --delete /var/www/ [email protected]:/var/www

You do not need a "*" and should not use it too.

To exclude/include files or directories, you should use this parameters:

--exclude 'to_exclude*'
--include 'to_include*'

Solution 2:

Your command was not working because when you were using /var/www/* as the source, your shell is performing globbing on it i.e. shell is expanding * to all files in that directory and the copying the files one by one, so here individual files have become the sources rather than the parent directory.

So, if you use /var/www/*, then you don't need --recursive option as * will causes the files to be copied (along with any directories with their contents), not the parent directory that contains the files. Because of the same reason --delete is not working, as --delete will remove files from destination directory that are not in the source directory, but you are copying files so its not removing files (expectedly).

This will make you more clear:

/foo$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test


/bar$ ls -l
-rw-rw-r-- 1 user user 0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user 0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user 0 Apr 16 17:56 spam


$ rsync -avz --ignore-existing --recursive --delete 
/foo/* /bar/

+ rsync -avz --ignore-existing --recursive --delete 
/foo/egg /foo/spam /foo/test /bar/

sending incremental file list
test/
test/hello

sent 173 bytes  received 39 bytes  424.00 bytes/sec
total size is 0  speedup is 0.00


/bar$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test

As you can see, i have used the source as /foo/* hence the rsync command being executed is

rsync -avz --ignore-existing --recursive --delete /foo/egg 
/foo/spam /foo/test /bar/

with * making shell to expand it and make all files individually as source arguments, not the parent directory as a whole (and you also don't need --recursive in this case).

So, if you want to make --delete work, run it as:

rsync -avz --ignore-existing --recursive --delete 
/var/www/ [email protected]:/var/www/