i'm write a script for automation copying file with rsync from server-a to server-b this is my script :

NOW=$(date +"%Y-%m")
rsync -au --ignore-existing /var/www/uploads/$NOW/* -e root@$NOW/.

when we are going to an next month like from October to November , i get this error on my script :


rsync: mkdir "/var/www/uploads/2014-11/." failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(605) [Receiver=3.0.9]
rsync: connection unexpectedly closed (9 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]

` how should i fix this error ? please help me


Firstly, make sure that the parent directory on the target exists. I.e. root@ 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 root@$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 root@$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).

| improve this answer | |

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

rsync -au --ignore-existing /var/www/uploads/$NOW/* -e root@$NOW
| improve this answer | |

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 root@
  • 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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.