A good[ish] website
Web development blog, loads of UI and JavaScript topics
A guide to syncing files between local and remote environment with rsync.
rsync
is an awesome tool, it’s designed to effortlessly move large quantities of files, locally or over the network.
If your rsync
is out of date, I have a little post on how to upgrade it.
rsync options source destination
Commonly used options:
-r
-z
-a
-rlptgoD
, meaning: preserves symbolic links, special and device files, modification times, group, owner, and permissions.-P
--progress
and --partial
, meaning it shows a progress bar and it’s possible to resume interrupted transfers.--delete
The usual set of option is -zaP
, which is easy to remember.
Basic example:
$ rsync -zaP --delete ./uploads -p 5555 bob@yourserver.com:/var/www/example.com/public_html
That’ll sync a local directory uploads/
to remote /var/www/example.com/public_html
. Local path can be relative.
More examples below.
Noteworthy thing: if you do commands like that a lot, you could put your ssh credentials into the
~/.ssh/config
file, then the host can be referred with a short name, here's an article on how to do that.
Make some test files:
$ mkdir rsync-test-{1..2}
$ touch rsync-test-1/file{1..50}
Syncing files from rsynctest1/
to rsynctest2/
is as follows:
$ rsync -r rsynctest1/ rsynctest2
Notice the forward slash /
after the source directory. This means that grab the contents of the directory, not the directory itself. Test the difference if you like:
$ rsync -r rsynctest1 rsynctest2
But really, the -a
option would fit here like fist in eye:
$ rsync -a rsynctest1/ rsynctest2
It preserves all the setting the directory has, symlinks, permissions etc.
Example syntax for moving a file to a server (assumes you set server shortname in ssh config):
$ rsync -zaP --delete uploads/ server_shortname:/path/to/uploads
Note: the --delete
option removes the files from the remote that are not present in the local, it's truly synchronizing the directories.
Btw: tab completion in the remote server is possible, see this post for more info.
Just "flip it and reverse it":
$ rsync -zaP --delete server_shortname:/path/to/uploads uploads/
Run it twice using the -u
flag.
-u
, --update
$ rsync -ur uploads/ server_shortname:/path/to/uploads
$ rsync -ur server_shortname:/path/to/uploads uploads/
With more options:
$ rsync -zuaP uploads/ server_shortname:/path/to/uploads
$ rsync -zuaP server_shortname:/path/to/uploads uploads/
Or use Unison, it’s a tool made just for that, but I’ve never used it myself.
The -z
option enables compression, but only for individual files, it wont compress the whole directory, which would be ideal if moving thousands of files for the first time.
To really bulldoze files over to a server, you could go like:
$ tar zcvf - ./source | ssh bob@example.com "cd /target/dir; tar xvzf -"
Here’s what that does:
If you want it shorter and more usable, wrap it to a function and put it to your .bashrc
or .bash_profile
, then you got it at your disposal anywhere:
function zipSync() {
local source=$1
local target=$2
# Get the host and path from the $target string
IFS=':' read -a array <<< "$target"
local host=${array[0]}
local destination=${array[1]}
tar zcvf - $source | ssh $host "cd $destination; tar xvzf -"
}
Example:
$ zipsync uploads my_server:/var/www/example.com/public_html
Problems with that function:
zipsync uploads -p 5555 bob@xmpl.com:/path/
cause the -p
is read as the second parameter.But:
Comments would go here, but the commenting system isn’t ready yet, sorry.