There are two issues with this command line:
find . -mtime -2 -exec rsync -av {} /destination/ \;`
Transferring path names
First, when giving (single) file names to rsync
and not simply a directory, it must be told explicitly to use the whole path and not only the filename for the destination. For this, use the option -R
. From the manual page to rsync(1):
-R, --relative
Use relative paths. This means that the full path names specified on the
command line are sent to the server rather than just the last parts
of the filenames. This is particularly useful when you want to send
several different directories at the same time. For example, if you
used this command:
rsync -av /foo/bar/baz.c remote:/tmp/
... this would create a file named baz.c in /tmp/ on the remote machine.
If instead you used
rsync -avR /foo/bar/baz.c remote:/tmp/
then a file named /tmp/foo/bar/baz.c would be created on the remote
machine, preserving its full path. These extra path elements are
called "implied directories" (i.e. the "foo" and the "foo/bar"
directories in the above example).
[...]
The manpage then continues on how to manipulate the path so that only parts of it will be present on the receiving side, but that is out of scope here.
Search for files only, not for directories
Second, find
called as above will not only report files, but also directories. When a directory name is given to rsync
as a source, it will synchronize that whole directory to the destination. This can be prevented using the additional test -type f
("type must be file") for find
. Be aware, though, that this will not only exclude directories, but also sockets, named pipes, block and char devices, and symlinks. For symlinks, you could use the -xtype
parameter instead, which will check the type of the symlink target.
Solution
So, the modified command line would look like this:
find . -type f -mtime -2 -exec rsync -av -R {} /destination/ \;
This will find
all files (-type f
) in the current path (.
) that have been modified within the last two days (-mtime -2
) and for each of them: execute (-exec
) rsync
, copying the file with the given name ({}
) to /destination/
, preserving most attributes (-a
), giving verbose output (-v
) and reproducing the whole path at the destination (-R
).