rsync - create all missing parent directories?

RsyncScp

Rsync Problem Overview


I'm looking for an rsync-like program which will create any missing parent directories on the remote side.

For example, if I have /top/a/b/c/d on one server and only /top/a exists on the remote server, I want to copy d to the remote server and have the b and c directories created as well.

The command:

rsync /top/a/b/c/d remote:/top/a/b/c

won't work because /tmp/a/b doesn't exist on the remote server. And if it did exist then the file d would get copied to the path /top/a/b/c.

This is possible to do with rsync using --include and --exclude switches, but it is very involved, e.g.:

rsync -v -r a dest:dir  \
  --include 'a/b'       \
  --include 'a/b/c'     \
  --include 'a/b/c/d'   \
  --include 'a/b/c/d/e' \
  --exclude 'a/*'       \
  --exclude 'a/b/*'     \
  --exclude 'a/b/c/*'   \
  --exclude 'a/b/c/d/*' 

will only copy a/b/c/d/e to dest:dir/a/b/c/d/e even if the intermediate directories have files. (Note - the includes must precede the excludes.)

Are there any other options?

Rsync Solutions


Solution 1 - Rsync

You may be looking for

rsync -aR

for example:

rsync -a --relative /top/a/b/c/d remote:/

See also this trick in other question.

Solution 2 - Rsync

rsync -aq --rsync-path='mkdir -p /tmp/imaginary/ && rsync' file user@remote:/tmp/imaginary/

From http://www.schwertly.com/2013/07/forcing-rsync-to-create-a-remote-path-using-rsync-path/, but don't copy and paste from there, his syntax is butchered.

it lets you execute arbitrary command to setup the path for rsync executables.

Solution 3 - Rsync

i suggest that you enforce the existence manually:

ssh user@remote mkdir -p /top/a/b/c
rsync /top/a/b/c/d remote:/top/a/b/c

this creates the target folder if it does not exists already.

Solution 4 - Rsync

According to https://unix.stackexchange.com/a/496181/5783, since rsync 2.6.7, --relative works if you use . to anchor the starting parent directory to create at the destination:

derek@DESKTOP-2F2F59O:~/projects/rsync$ mkdir --parents top1/a/b/c/d
derek@DESKTOP-2F2F59O:~/projects/rsync$ mkdir --parents top2/a
derek@DESKTOP-2F2F59O:~/projects/rsync$ rsync --recursive --relative --verbose top1/a/./b/c/d top2/a/
sending incremental file list
b/
b/c/
b/c/d/

sent 99 bytes  received 28 bytes  254.00 bytes/sec
total size is 0  speedup is 0.00

Solution 5 - Rsync

--relative does not work for me since I had different setup. Maybe I just didn't understood how --relative works, but I found that the

ssh remote mkdir -p /top/a/b/c
rsync /top/a/b/c/d remote:/top/a/b/c

is easy to understand and does the job.

Solution 6 - Rsync

I was looking for a better solution, but mine seems to be better suited when you have too many sub-directories to create them manually.

Simply use cp as an intermediate step with the --parents option

cp --parents /your/path/sub/dir/ /tmp/localcopy
rsync [options] /tmp/localcopy/* remote:/destination/path/

cp --parents will create the structure for you.

You can call it from any subfolder if you want only one subset of the parent folders to be copied.

Solution 7 - Rsync

A shorter way in Linux to create rsync destination paths is to use the '$_' Special Variable. (I think, but cannot confirm, that it is also the same in OSX).

'$_' holds the value of the last argument of the previous command executed. So the question could be answered with:

ssh remote mkdir -p /top/a/b/c/ && rsync -avz /top/a/b/c/d remote:$_

Solution 8 - Rsync

As of version 3.2.3 (6 Aug 2020), rynsc has a flag for this purpose.

From the rsync manual page (man rsync):

--mkpath                 create the destination's path component

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionErikRView Question on Stackoverflow
Solution 1 - RsyncBaluView Answer on Stackoverflow
Solution 2 - RsyncEddieView Answer on Stackoverflow
Solution 3 - RsyncmnagelView Answer on Stackoverflow
Solution 4 - RsyncDerek MaharView Answer on Stackoverflow
Solution 5 - RsyncandrejView Answer on Stackoverflow
Solution 6 - RsyncjessemeView Answer on Stackoverflow
Solution 7 - RsyncDigView Answer on Stackoverflow
Solution 8 - RsyncRaZ0rrView Answer on Stackoverflow