19

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/* root@mydomaintest.com:/var/www

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

1
  • instead of /var/www/* all you need to do is /var/www/.
    – Sparkler
    Mar 30 at 21:16
22

Use this command:

rsync --archive --verbose --compress --ignore-existing --delete /var/www/ root@mydomaintest.com:/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*'
7
  • Okay let me try this :) Apr 16 '15 at 11:47
  • 2
    So is the "*" that's causing the the --delete command not working? Apr 16 '15 at 11:49
  • 2
    That's how it looks. :)
    – A.B.
    Apr 16 '15 at 11:51
  • 3
    --recursive is overabundant because option -a already includes it
    – Temak
    Jul 8 '16 at 9:44
  • 2
    The "*" could be important in some cases because it excludes files/directories that begin with ".". For example I use it when using rsync to copy a directory maintained under git from a development machine to a production machine. I don't want to sync the .git repository directory, or files like .gitignore, just the working tree,including files at the top-level as well as subdirectories.
    – sootsnoot
    Sep 14 '16 at 4:01
21

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/ root@mydomaintest.com:/var/www/
2
  • 4
    Excellent explanation pointing out the real issue: using '*' to expand the source list. Jul 8 '16 at 14:47
  • As noted in my comment on the accepted answer, the * can be useful to exclude things like files and directories beginning with ".". Though as you note, this means files and directories removed from the top level in the source won't be removed from the destination directory. For myself, I don't care whether top-level files get properly deleted from the destination, only files below subdirectories matter. Removing a top-level subdirectory is far less likely than adding one, and I'm willing to do a manual rm -r on the destination in that unlikely case.
    – sootsnoot
    Sep 14 '16 at 4:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.