Copying Only Directories With Rsync

shell

It's sometimes necessary to copy a directory tree from one place to another, preserving the directory structure, while not copying the contents of the directories themselves. This is actually fairly easy to do with rsync. We're going to go through an example of copying the 'src' directory into 'dst'. Because we would like to test this first to make sure it will work, we'll take advantage of rsync's dry-run feature. Here is the command:

rsync -av -n --include='*/' --exclude='*' src/ dst

And here is the source directory tree, with a few files thrown in for good measure:

dmaxwell@serenity:~/tmp$ ls -R src src/bar: src/baz: sitemap_gen.pl sitemap.xml ssl_error.png test1.png test2.png src/foo: src/quux: blarg.png bookmarks_3_1_12.html cap1_inside.pcap cap3.pcap config.xml example_urllist.txt fg.png test src/quux/test: README

Now for the options:

The order of the include and exclude options is important, since for any given file path, the first matching pattern is used. That means that if you put the include after the exclude, nothing will be matched by the include (in this case resulting in an empty copy). Also be aware that the trailing slash on the src/ argument is necessary. If we omit it, the src directory itself is copied into dst, rather than the contents of src. An important but subtle distinction. Now here is our dry-run:

dmaxwell@serenity:~/tmp$ rsync -av -n --include='*/' --exclude='*' src/ dst sending incremental file list created directory dst ./ bar/ baz/ foo/ quux/ quux/test/ sent 152 bytes received 35 bytes 374.00 bytes/sec total size is 0 speedup is 0.00 (DRY RUN)

We can see that rsync is just copying directories, and it's safe to run the command without the -n:

dmaxwell@serenity:~/tmp$ rsync -av --include='*/' --exclude='*' src/ dst sending incremental file list created directory dst ./ bar/ baz/ foo/ quux/ quux/test/ sent 152 bytes received 35 bytes 374.00 bytes/sec total size is 0 speedup is 0.00 dmaxwell@serenity:~/tmp$ ls -R dst dst: bar baz foo quux dst/bar: dst/baz: dst/foo: dst/quux: test dst/quux/test:

There we have it - we successfully copied the directory structure from src/ into dst/, without copying any files. Rsync is an amazing tool and I'll have more to say on it in the future.