Synchronizing a Remote Directory with a Local Directory Using rsync, ssh, and Compression
Introduction
Keeping remote directories synchronized with local ones is a common requirement for system administrators, developers, and IT professionals. The tool of choice for this task is rsync, a powerful, fast, and reliable file-copying utility. Yes, I always keep forgetting how to use rsync over ssh, and how to deal with the strange way rsync handles the trailing / in directories.
So, what I have is:
Remote server reachable over ssh, called server.
A directory on that server called /home/user/mystuff
A local directory on my Linux or Macos machine called ~/mystuff/
What I want:
I want my local machine to reflect what is on the remote server and only downloading changed files or directories, while keeping the time stamps and compressing the download to speed up things.
I have already password-less login to my remote server set up with a private/public key.
Alright, let’s get to work.
Basic Syntax
The general rsync syntax is:
rsync [OPTIONS] source destination
In our case, the syntax is:
rsync -avz -e "ssh" user@server:/home/user/mystuff/ mystuff/
Now, for future understanding, let’s break down the above command
1. rsync
This is the command itself.
2. -a (Archive Mode)
The -a option ensures that all essential file attributes are preserved:
- Permissions (chmod)
- Timestamps (mtime)
- Symbolic links
- File ownership
- Recursive transfer (subdirectories included)
- This is a shorthand for multiple options (-rlptgoD).
3. -v (Verbose Mode)
-v provides progress updates, making it clear what is happening.
4. -z (Compression)
Compression reduces the amount of data transferred, making the operation faster, especially over slow networks.
5. -e "ssh" (Using SSH as the Transport)
Specifies SSH as the transport protocol for secure communication.
In my case, on my Linux servers, I always change the default ssh port from 22 to 7122. So, in my case the command would be:
rsync -avz -e "ssh -p 7122" user@remote_server:/home/user/mystuff/ mystuff/
For me, one tricky part is always remembering how to treat the trailing slash (/) when working with rsync. So here it is:
With /: Syncs the contents of mystuff/ into mystuff/ locally
Without /: Syncs the directory mystuff inside mystuff/ locally
That about does it. But wait! What if a file no longer exists on the remote machine. How do I mirror my local directory perfectly with the remote host?
To keep a perfect mirror:
rsync -avz --delete -e "ssh" user@remote_server:/home/user/mystuff/ mystuff/
Are you ready for 2 more Ninja tricks that will impress your friends?
Let’s limit the bandwidth we use with our rsync mirroring. The following options limits the download to 1000KB/sec:
rsync -avz --bwlimit=1000 -e "ssh" user@remote_server:/home/user/mystuff/ mystuff/
And finally, show the progress of the mirroring process, as we go:
rsync -avz --progress -e "ssh" user@remote_server:/home/user/mystuff/ mystuff/
You can of course combine all these options for a super-duper mirroring setup. And, of course you can add the rsync into your crontab for recurring mirroring, let’s say you want to mirror on an hourly basis. Here is the crontab entry:
0 * * * * rsync -avz --progress --bwlimit=1000 -delete -e "ssh -p 7122" user@remote_server:/home/user/mystuff/ mystuff/