I would like to rsync
from local computer to server. On a directory that does not exist, and I want rsync
to create that directory on the server first.
How can I do that?
If you have more than the last leaf directory to be created, you can either run a separate ssh ... mkdir -p
first, or use the --rsync-path
trick as explained here :
rsync -a --rsync-path="mkdir -p /tmp/x/y/z/ && rsync" $source user@remote:/tmp/x/y/z/
Or use the --relative
option as suggested by Tony. In that case, you only specify the root of the destination, which must exist, and not the directory structure of the source, which will be created:
rsync -a --relative /new/x/y/z/ user@remote:/pre_existing/dir/
This way, you will end up with /pre_existing/dir/new/x/y/z/
And if you want to have "y/z/" created, but not inside "new/x/", you can add ./
where you want --relative
to begin:
rsync -a --relative /new/x/./y/z/ user@remote:/pre_existing/dir/
would create /pre_existing/dir/y/z/.
Assuming you are using ssh to connect rsync, what about to send a ssh command before:
ssh user@server mkdir -p existingdir/newdir
if it already exists, nothing happens
rsync
, therefore, no answer.
ssh
is not supported and rsync
connects to the rsync daemon
on the remote end.
From the rsync
manual page (man rsync
):
--mkpath create the destination's path component
--relative
with this flag, you can simply leave a trailing slash on both source and destination paths and all recursive files/folders will be automatically synced between them...
The -R, --relative
option will do this.
For example: if you want to backup /var/named/chroot
and create the same directory structure on the remote server then -R
will do just that.
/./
in the source path. See man page for details.
rsync
won't create directories automatically if target folders don't exist. Sigh.
--relative
. It might not do what you think.
--relative
in conjunction with /./
is what most newbies will be looking for. rsync -avz -e ssh --progress --relative ~/./Desktop/ TARGET_IP:~/
will copy the contents of the desktop to the target desktop. Don't know how differences in usernames might affect this.
this worked for me:
rsync /dev/null node:existing-dir/new-dir/
I do get this message :
skipping non-regular file "null"
but I don't have to worry about having an empty directory hanging around.
I don't think you can do it with one rsync command, but you can 'pre-create' the extra directory first like this:
rsync --recursive emptydir/ destination/newdir
where 'emptydir' is a local empty directory (which you might have to create as a temporary directory first).
It's a bit of a hack, but it works for me.
cheers
Chris
rsync /dev/null node:existing-dir/new-dir/
suggestion above.
This answer uses bits of other answers, but hopefully it'll be a bit clearer as to the circumstances. You never specified what you were rsyncing - a single directory entry or multiple files.
So let's assume you are moving a source directory entry across, and not just moving the files contained in it.
Let's say you have a directory locally called data/myappdata/
and you have a load of subdirectories underneath this. You have data/
on your target machine but no data/myappdata/
- this is easy enough:
rsync -rvv /path/to/data/myappdata/ user@host:/remote/path/to/data/myappdata
You can even use a different name for the remote directory:
rsync -rvv --recursive /path/to/data/myappdata user@host:/remote/path/to/data/newdirname
If you're just moving some files and not moving the directory entry that contains them then you would do:
rsync -rvv /path/to/data/myappdata/*.txt user@host:/remote/path/to/data/myappdata/
and it will create the myappdata
directory for you on the remote machine to place your files in. Again, the data/
directory must exist on the remote machine.
Incidentally, my use of -rvv
flag is to get doubly verbose output so it is clear about what it does, as well as the necessary recursive behaviour.
Just to show you what I get when using rsync (3.0.9 on Ubuntu 12.04)
$ rsync -rvv *.txt user@remote.machine:/tmp/newdir/
opening connection using: ssh -l user remote.machine rsync --server -vvre.iLsf . /tmp/newdir/
user@remote.machine's password:
sending incremental file list
created directory /tmp/newdir
delta-transmission enabled
bar.txt
foo.txt
total: matches=0 hash_hits=0 false_alarms=0 data=0
Hope this clears this up a little bit.
rsync -rvv /path/to/data/myappdata user@host:/remote/path/to/data/myappdata
but what it created on the target is /remote/path/to/data/myappdata/myappdata/
rsync -rvv /path/to/data/myappdata/ user@host:/remote/path/to/data/myappdata
eg:
from: /xxx/a/b/c/d/e/1.html
to: user@remote:/pre_existing/dir/b/c/d/e/1.html
rsync:
cd /xxx/a/ && rsync -auvR b/c/d/e/ user@remote:/pre_existing/dir/
rsync source.pdf user1@192.168.56.100:~/not-created/target.pdf
If the target file is fully specified, the directory ~/not-created
is not created.
rsync source.pdf user1@192.168.56.100:~/will-be-created/
But the target is specified with only a directory, the directory ~/will-be-created
is created. /
must be followed to let rsync know will-be-created
is a directory.
use rsync twice~
1: tranfer a temp file, make sure remote relative directories has been created.
tempfile=/Users/temp/Dir0/Dir1/Dir2/temp.txt
# Dir0/Dir1/Dir2/ is directory that wanted.
rsync -aq /Users/temp/ rsync://remote
2: then you can specify the remote directory for transfer files/directory
tempfile|dir=/Users/XX/data|/Users/XX/data/
rsync -avc /Users/XX/data rsync://remote/Dir0/Dir1/Dir2
# Tips: [SRC] with/without '/' is different
This creates the dir tree /usr/local/bin
in the destination and then syncs all containing files and folders recursively:
rsync --archive --include="/usr" --include="/usr/local" --include="/usr/local/bin" --include="/usr/local/bin/**" --exclude="*" user@remote:/ /home/user
Compared to mkdir -p
, the dir tree even has the same perms as the source.
If you are using a version or rsync that doesn't have 'mkpath', then --files-from can help. Suppose you need to create 'mysubdir' in the target directory
Create 'filelist.txt' to contain mysubdir/dummy
mkdir -p source_dir/mysubdir/
touch source_dir/mysubdir/dummy
rsync --files-from='filelist.txt' source_dir target_dir
rsync will copy mysubdir/dummy to target_dir, creating mysubdir in the process. Tested with rsync 3.1.3 on Raspberry Pi OS (debian).
Success story sharing
mkdir
, so i'm using the hack:--rsync-path="echo f > /public/.keep && rsync /public/.keep /public/newfolder/ && rsync" \
it does create an extra file but you can remove later.&&
?