129

Currently i only RSync-ing the Directories as like:

* * * * * rsync -avz /var/www/public_html/images root@<remote-ip>:/var/www/public_html

So how do i rsync one single file like, /var/www/public_html/.htaccess ?

夏期劇場
  • 17,821
  • 44
  • 135
  • 217

5 Answers5

195

You do it the same way as you would a directory, but you specify the full path to the filename as the source. In your example:

rsync -avz   --status=progress  /var/www/public_html/.htaccess root@<remote-ip>:/var/www/public_html/

As mentioned in the comments: since -a includes recurse, one little typo can make it kick off a full directory tree transfer, so a more fool-proof approach might to just use -vz, or replace it with -lptgoD.

Tarick Welling
  • 3,119
  • 3
  • 19
  • 44
Michael Place
  • 2,986
  • 1
  • 19
  • 18
  • 23
    Also if you are only sending one file you may want to add the "--progress" parameter so you can watch it's progress. – JoshStrange Feb 28 '14 at 20:48
  • does this mean that you still need a module in rsyncd.conf with a directory above the file (eg. with refuse option delete), or can you upload files anywhere on the server by just specifying it's path? The man page isn't really clear about that. –  Jun 18 '16 at 09:11
  • 3
    -a includes recursive and that is not needed for a single file not sure if I would use that flag for single file as it can lead to unintended behavior if the filename by accident becomes a directory. – redanimalwar Oct 25 '17 at 13:44
  • 4
    --partial --stats --progress << These flags are helpful if it's a really large file and may have to be resumed after a broken transfer. – Ahi Tuna Sep 04 '18 at 18:51
18

Basic syntax

rsync options source destination

Example

rsync -az /var/www/public_html/filename root@<remote-ip>:/var/www/public_html

Read more

Techie
  • 44,706
  • 42
  • 157
  • 243
16

Michael Place's answer works great if, relative to the root directory for both the source and target, all of the directories in the file's path already exist.

But what if you want to sync a file with this source path:

/source-root/a/b/file

to a file with the following target path:

/target-root/a/b/file

and the directories a and b don't exist?

You need to run an rsync command like the following:

rsync -r --include="/a/" --include="/a/b/" --include="/a/b/file" --exclude="*" [source] [target]
Kenny Evitt
  • 9,291
  • 5
  • 65
  • 93
  • 2
    Wouldn't it be safer to just copy the individual file to an existing folder or create the folders in advance? In case of folder or folder content syncing let's rsync create all subfolders, after all it's its work, but in this particular case it's too much hassle and tricky the --include parameters just to copy individual files. – Tulains Córdova Feb 29 '16 at 14:44
  • @user1598390 I'm not sure what scenario you're assuming, or imagining, where this would be less safe, but if you were trying to remember the specific form of this command and you didn't do it frequently, then yes it's probably less safe then copying the single file. It may be safer tho if the file is large, i.e. because rsync automatically handles most errors that could occur during copying. For some context, my syntax was particularly useful for me because I had written code that generated commands in this form so, given sufficient tests covering the relevant code, these commands are 'safe'. – Kenny Evitt Feb 29 '16 at 14:51
2

Aside from the good above answers, rsync expects the destination to be a directory and not a filename. Suppose you are copying the word list file words to /tmp, don't do this:

 rsync -az /user/share/dict/words /tmp/words    # does not work

'cp' is tolerant of this form, but rsync isn't - it will fail because it doesn't see a directory at /tmp/words. Snip off the destination filename and it works:

 rsync -az /user/share/dict/words /tmp

Note that rsync won't let you change the filename during the copy, and cp will.

1

To date, two of the answers aren't quite right, they'll get more than one file, and the other isn't as simple as it could be, here's a simpler answer IMO.

The following gets exactly one file, but you have to create the dest directory with mkdir. This is probably the fastest option:

mkdir -p ./local/path/to/file
rsync user@remote:/remote/path/to/file/ -zarv --include "filename" --exclude "*" ./local/path/to/file/

If there is only one instance of file in /remote/path, rsync can create directories for you if you do the following. This will probably take a little more time because it searches more directories. Plus it's will create empty directories for directories in /remote/path that are not in ./local

cd ./local
rsync user@remote:/remote/path -zarv --include "*/" --include "filename" --exclude "*" .

Keep in mind that the order of --include and --exclude matters.

Samuel
  • 8,063
  • 8
  • 45
  • 41