Local Transfer Mode
Local rsync transfers follow the syntax:
rsync [OPTION…] SOURCE… [DESTINATION]
[root@node1 ~]# touch demo.txt
[root@node1 ~]# ls -l
total 0
-rw-r--r-- 1 root root 0 Apr 12 17:52 demo.txt
[root@node1 ~]# ls -l /tmp
total 0
# Copy demo.txt to /tmp directory
[root@node1 ~]# rsync -avz demo.txt /tmp/
sending incremental file list
demo.txt
sent 83 bytes received 35 bytes 236.00 bytes/sec
total size is 0 speedup is 0.00
[root@node1 ~]# ls -l /tmp
total 0
-rw-r--r-- 1 root root 0 Apr 12 17:52 demo.txt
# Repeat transfer: rsync skips unchanged files by default (incremental transfer)
[root@node1 ~]# rsync -avz demo.txt /tmp/
sending incremental file list
sent 43 bytes received 12 bytes 110.00 bytes/sec
total size is 0 speedup is 0.00
The trailing slash on source directories changes the behavior:
# Copy *contents* of project_files directory (trailing / copies content only)
[root@node1 ~]# ls -l project_files/
total 0
-rw-r--r-- 1 root root 0 Apr 12 17:52 file1.txt
-rw-r--r-- 1 root root 0 Apr 12 17:55 file2.txt
[root@node1 ~]# rm -rf /tmp/*
[root@node1 ~]# ls -l /tmp/
total 0
[root@node1 ~]# rsync -avz project_files/ /tmp/
sending incremental file list
./
file1.txt
file2.txt
sent 162 bytes received 57 bytes 438.00 bytes/sec
total size is 0 speedup is 0.00
[root@node1 ~]# ls -l /tmp/
total 0
-rw-r--r-- 1 root root 0 Apr 12 17:52 file1.txt
-rw-r--r-- 1 root root 0 Apr 12 17:55 file2.txt
# Copy the entire project_files directory to destination (no trailing / copies the folder itself)
[root@node1 ~]# rm -rf /tmp/*
[root@node1 ~]# ls -l /tmp/
total 0
[root@node1 ~]# rsync -avz project_files /tmp/
sending incremental file list
project_files/
project_files/file1.txt
project_files/file2.txt
sent 178 bytes received 58 bytes 472.00 bytes/sec
total size is 0 speedup is 0.00
[root@node1 ~]# tree /tmp/
/tmp/
└── project_files
├── file1.txt
└── file2.txt
1 directory, 2 files
Remote Shell Transfre Mode
This mode transfers files over SSH, with two operation directions:
- Pull (download from remote to local):
rsync [OPTION...] [USER@]HOST:SOURCE [LOCAL_DEST] - Push (upload from local to remote):
rsync [OPTION...] LOCAL_SOURCE [USER@]HOST:DEST
# Pull example: download a test file from 10.0.0.7 to local current directory
# Create test file on remote host first
[root@remote-host ~]# touch remote_test.txt
[root@remote-host ~]# ls -l
total 0
-rw-r--r-- 1 root root 0 Apr 12 18:01 remote_test.txt
# Run pull command on local client
[root@local-client ~]# rsync -avz root@10.0.0.7:/root/remote_test.txt ./
The authenticity of host '10.0.0.7 (10.0.0.7)' can't be established.
ECDSA key fingerprint is SHA256:xdfdFLkrn/v6sHcb/REfZ1PvAlRIpB4AnT6syjZ1rvM.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.0.7' (ECDSA) to the list of known hosts.
root@10.0.0.7's password:
receiving incremental file list
remote_test.txt
sent 43 bytes received 84 bytes 36.29 bytes/sec
total size is 0 speedup is 0.00
[root@local-client ~]# ls -l
total 0
-rw-r--r-- 1 root root 0 Apr 12 18:01 remote_test.txt
Push example:
# Push local project_files directory to remote 10.0.0.7's /opt folder
[root@local-client ~]# rsync -avz project_files root@10.0.0.7:/opt
root@10.0.0.7's password:
sending incremental file list
project_files/
project_files/file1.txt
project_files/file2.txt
sent 178 bytes received 58 bytes 94.40 bytes/sec
total size is 0 speedup is 0.00
# Verify on remote host
[root@remote-host ~]# ls -l /opt/
total 0
drwxr-xr-x 2 root root 32 Apr 12 17:55 project_files
Key rule: The source file/directory always comes first in the command. For pull, the remote server is in the first position; for push, the remote server is at the end.
You can also use domain names or custom hostnames (configured via /etc/hosts) instead of raw IPs:
# Add custom hostname mapping locally
[root@local-client ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain
::1 localhost localhost.localdomain
10.0.0.7 web01
[root@local-client ~]# rsync -avz project_files root@web01:/opt
The authenticity of host 'web01 (10.0.0.7)' can't be established.
ECDSA key fingerprint is SHA256:xdfdFLkrn/v6sHcb/REfZ1PvAlRIpB4AnT6syjZ1rvM.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'web01' (ECDSA) to the list of known hosts.
root@web01's password:
sending incremental file list
project_files/
project_files/file1.txt
project_files/file2.txt
sent 178 bytes received 58 bytes 52.44 bytes/sec
total size is 0 speedup is 0.00
Rsync Daemon Mode (Enterprise Production Usage)
This is the most widely used mode in production environments, running rsync as a persistent background service.
Server Setup Steps
- Install rsync
yum -y install rsync
[root@rsync-server ~]# rpm -qa rsync
rsync-3.1.2-12.el7_9.x86_64
- Edit the main configuration file
/etc/rsyncd.conf
uid = rsync
gid = rsync
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
#####################################
[backup]
comment = Shared backup storage
path = /backup
- Create required system users, files and directories
# Create virtual system user for rsync
[root@rsync-server ~]# useradd -M -s /sbin/nologin rsync
[root@rsync-server ~]# id rsync
uid=1000(rsync) gid=1000(rsync) groups=1000(rsync)
# Create auth password file (format: username:password)
[root@rsync-server ~]# echo "rsync_backup:123456" > /etc/rsync.passwd
# Password file *must* have 600 permissions, otherwise rsync will refuse to load it
[root@rsync-server ~]# chmod 600 /etc/rsync.passwd
[root@rsync-server ~]# ls -l /etc/rsync.passwd
-rw------- 1 root root 20 Apr 12 19:26 /etc/rsync.passwd
# Create shared backup directory and set correct ownership
[root@rsync-server ~]# mkdir /backup
[root@rsync-server ~]# chown rsync:rsync /backup/
[root@rsync-server ~]# ls -ld /backup/
drwxr-xr-x 2 rsync rsync 6 Apr 12 19:28 /backup/
- Start service and enable auto-start on boot
[root@rsync-server ~]# systemctl start rsyncd
[root@rsync-server ~]# systemctl enable rsyncd
Created symlink from /etc/systemd/system/multi-user.target.wants/rsyncd.service to /usr/lib/systemd/system/rsyncd.service.
# Verify port 873 is listening
[root@rsync-server ~]# ss -tulpn | grep 873
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 16729/rsync
tcp6 0 0 :::873 :::* LISTEN 16729/rsync
Client Usage
Daemon mode syntax uses double colons to separate host and module name:
- Push:
rsync [OPTIONS] LOCAL_SOURCE USER@RSYNC_SERVER::MODULE_NAME - Pull:
rsync [OPTIONS] USER@RSYNC_SERVER::MODULE_NAME/SOURCE LOCAL_DEST
Test push example:
# Push local /opt/project_files to the backup module on 10.0.0.41 server
[root@rsync-client ~]# rsync -avz /opt/project_files rsync_backup@10.0.0.41::backup
Password:
sending incremental file list
project_files/
project_files/file1.txt
project_files/file2.txt
sent 182 bytes received 66 bytes 70.86 bytes/sec
total size is 0 speedup is 0.00
Pull example:
# Pull all content from the backup module to local ~/backup directory
# Rsync will automatically create the destination directory if it does not exist
[root@rsync-client ~]# rsync -avz rsync_backup@10.0.0.41::backup /root/backup
Password:
receiving incremental file list
created directory /root/backup
./
1.txt
2.txt
3.txt
4.txt
5.txt
project_files/
project_files/file1.txt
project_files/file2.txt
sent 176 bytes received 528 bytes 281.60 bytes/sec
total size is 0 speedup is 0.00
Common gotcha when downloading specific files:
# Correct: pull 5.txt to existing download directory
[root@rsync-client ~]# mkdir download_dir
[root@rsync-client ~]# rsync -avz rsync_backup@10.0.0.41::backup/5.txt ~/download_dir
Password:
receiving incremental file list
5.txt
sent 43 bytes received 92 bytes 90.00 bytes/sec
total size is 0 speedup is 0.00
[root@rsync-client ~]# ls -l ~/download_dir/
total 0
-rw-r--r-- 1 root root 0 Apr 12 19:36 5.txt
# Incorrect: destination directory does not exist
[root@rsync-client ~]# rm -rf *
[root@rsync-client ~]# rsync -avz rsync_backup@10.0.0.41::backup/5.txt ~/download_dir
Password:
receiving incremental file list
5.txt
sent 43 bytes received 92 bytes 54.00 bytes/sec
total size is 0 speedup is 0.00
[root@rsync-client ~]# ls -l ~/
total 0
-rw-r--r-- 1 root root 0 Apr 12 19:36 download_dir # Rsync creates a file named download_dir instead of a directory
Key Summary
1. Rsync supports incremental transfer, only copies changed files, and uses the quick check algorithm to quickly skip unchanged files, making it more efficient than full copy tools.
2. Three transfer modes core points:
- Local mode: Used for local file copying, similar to cp but with better performance for repeated transfers.
- Remote shell mode: Transfers over SSH for ad-hoc use:
Push: `rsync -avz local_file root@remote_host:/dest/path/`
Pull: `rsync -avz root@remote_host:/remote/source/file ./`
- Daemon mode (enterprise recommended):
Server setup key notes:
1. Use a dedicated system user to run the rsync service
2. Auth password file must have 600 permissions, formatted as `username:password`
3. Configure module name, corresponding storage path, and set path ownership to the rsync user
Client usage:
Push: `rsync -avz local_source rsync_user@server_ip::module_name`
Pull: `rsync -avz rsync_user@server_ip::module_name/remote_file ./local_dest`