rsync: mkdir "2014-11/." failed: No such file or directory (2)

Firstly, make sure that the parent directory on the target exists. I.e. [email protected]:/var/www/uploads should exist. I think with your formulation, the trailing . refers to a directory which rsync tries to create, and it can't do so unless the parent directory already exists. ie the parent is [email protected]:/var/www/uploads/$NOW.

Secondly, realise that the behaviour of rsync is subtly different to cp in various ways with the trailing '/' on the file name. I find the safest and most intuitive way to do things is to use a trailing / on the end of all directories. Like so:

rsync -au --ignore-existing /var/www/uploads/$NOW/ -e [email protected]:/var/www/uploads/$NOW/

Unlike cp, rsync will reliably copy the content of the directory in the source argument to the content of the target directory, creating the target directory if necessary (though it's parent must exist), and not putting the source directory (ie the parent) inside the target directory if the target already exists.

This is slightly different to what you were doing though in that the way you did it would exclude files with a name starting with . in the source directory, and would fail if the list of files being copied was too long (bash expansion capped at a total command line length of around 32K characters if memory serves me right).


The trailing dot needs to be removed, change the script to:

rsync -au --ignore-existing /var/www/uploads/$NOW/* -e [email protected]:/var/www/uploads/$NOW

Try this to have rsync create all needed directories on the destionation:

NOW=$(date +"%Y-%m")
rsync -au --ignore-existing --relative /var/www/uploads/$NOW [email protected]:/var/www/uploads/
  • added --relative to have rsync create the directory tree on the destination.
  • No slash after source, so that the last directory ("$NOW") also gets created on the destination, not only it's content.
  • Removed "$NOW" from destination since it will be created if needed.
  • removed your lonely -e option which looks like a mistake (it would need an argument: "This option allows you to choose an alternative remote shell program to use for communication").

Or see this answer for more details and alternatives.