rsync命令最全用法指南
rsync(remote sync)是 Linux/Unix 下最强大的文件同步和备份工具。它采用增量传输算法,只传输文件的变化部分,因此速度极快、效率极高。本文涵盖 rsync 从基础到高级的所有用法。
目录
- rsync 基础概念
- 基本语法与核心参数
- 本地同步
- 远程同步(通过 SSH)
- rsync 守护进程模式
- 增量备份策略
- 过滤与排除规则
- 删除与镜像同步
- 高级传输控制
- rsync 与 find 结合
- 自动化备份脚本
- rsync 在 Windows 上的使用
- 性能优化
- 故障排查
- 常用速查表
1. rsync 基础概念
什么是 rsync?
rsync 是一个快速、多功能的文件复制工具。它的核心优势在于 增量传输 —— 只传输源端和目标端之间有差异的数据块,而非整个文件。
rsync 的核心算法
源文件 目标文件
│ │
├─── 文件分块(Block Matching)──→│
│ (rolling checksum + MD5) │
│ │
│←── 差异报告 ───────────────────│
│ (哪些块已有,哪些缺失) │
│ │
├─── 只传输缺失的块 ────────────→│
│ │
│←── 重组完整文件 ───────────────│
rsync vs cp vs scp
| 特性 | cp | scp | rsync |
|---|---|---|---|
| 增量传输 | ❌ | ❌ | ✅ |
| 断点续传 | ❌ | ❌ | ✅ (--partial) |
| 删除同步 | ❌ | ❌ | ✅ (--delete) |
| 压缩传输 | ❌ | ✅ (-C) | ✅ (-z) |
| 带宽限制 | ❌ | ❌ | ✅ (--bwlimit) |
| 排除文件 | ❌ | ❌ | ✅ (--exclude) |
| 保留权限 | 部分 | ✅ (-p) | ✅ (-a) |
| 远程传输 | ❌ | ✅ | ✅ |
rsync 的三种工作模式
| 模式 | 语法 | 说明 |
|---|---|---|
| 本地模式 | rsync [选项] 源 目标 |
本机文件同步 |
| 远程 Shell | rsync [选项] 源 user@host:目标 |
通过 SSH 传输 |
| 守护进程 | rsync [选项] 源 user@host::模块/目标 |
连接 rsync daemon |
2. 基本语法与核心参数
基本语法
rsync [选项]... 源... 目标
# 可以有多个源,但只能有一个目标
rsync [选项] 源1 源2 源3 目标
核心参数详解
最常用的参数组合
# 最经典的参数组合:-avz
rsync -avz 源 目标
# -a: 归档模式(= -rlptgoD)
# -v: 详细输出
# -z: 压缩传输
参数完整列表
| 参数 | 完整名 | 说明 |
|---|---|---|
-a |
--archive |
归档模式,等于 -rlptgoD |
-r |
--recursive |
递归传输目录 |
-l |
--links |
保留符号链接 |
-p |
--perms |
保留权限 |
-t |
--times |
保留修改时间 |
-g |
--group |
保留所属组 |
-o |
--owner |
保留所有者(需 root) |
-D |
保留设备文件和特殊文件(= --devices --specials) |
|
-v |
--verbose |
详细输出 |
-vv |
更详细 | |
-vvv |
调试级别 | |
-z |
--compress |
压缩传输数据 |
-n |
--dry-run |
模拟运行,不实际传输 |
--delete |
删除目标中源端不存在的文件 | |
-u |
--update |
跳过目标中更新的文件 |
-c |
--checksum |
使用校验和而非时间和大小判断 |
-W |
--whole-file |
传输整个文件(禁用增量) |
-P |
= --partial --progress |
|
--partial |
保留传输部分文件(断点续传) | |
--partial-dir=DIR |
断点续传文件存放目录 | |
--progress |
显示传输进度 | |
-h |
--human-readable |
人性化显示数字 |
--bwlimit=RATE |
限制传输速率 | |
-e |
--rsh=COMMAND |
指定远程 Shell |
--exclude=PATTERN |
排除匹配的文件 | |
--exclude-from=FILE |
从文件读取排除规则 | |
--include=PATTERN |
包含匹配的文件 | |
--include-from=FILE |
从文件读取包含规则 | |
--max-size=SIZE |
最大文件大小限制 | |
--min-size=SIZE |
最小文件大小限制 | |
--link-dest=DIR |
硬链接到之前的备份(增量备份) | |
--backup |
-b |
创建备份 |
--backup-dir=DIR |
备份存放目录 | |
--suffix=SUFFIX |
备份文件后缀 | |
--remove-source-files |
传输后删除源文件 | |
--ignore-errors |
即使有 IO 错误也删除 | |
--force |
强制删除非空目录 | |
--existing |
只更新已存在的文件 | |
--ignore-existing |
只传输新文件 | |
--max-delete=NUM |
最多删除文件数 | |
--delay-updates |
延迟更新(最后原子替换) | |
--stats |
显示传输统计 | |
--version |
查看版本 |
3. 本地同步
基本本地复制
# 复制单个文件
rsync -v /path/to/source.txt /path/to/destination/
# 复制目录(注意斜杠!)
rsync -av /path/to/source/ /path/to/destination/
# 源目录末尾的 / 表示「复制目录内容」,不包含目录本身
rsync -av /path/to/source /path/to/destination/
# 源目录没有 / 表示「复制目录本身」
⚠️ 斜杠陷阱(最重要的概念)
# 情况 1:源带斜杠 → 复制内容
rsync -av /data/project/ /backup/project/
# 结果:/backup/project/ 里面有 project 的内容
# 情况 2:源不带斜杠 → 复制目录本身
rsync -av /data/project /backup/
# 结果:/backup/project/ 里面有 project 的内容
# 图示说明
# 源目录结构:
# /data/project/
# ├── index.html
# ├── style.css
# └── app.js
# rsync -av /data/project/ /backup/
# 结果:
# /backup/
# ├── index.html
# ├── style.css
# └── app.js
# rsync -av /data/project /backup/
# 结果:
# /backup/
# └── project/
# ├── index.html
# ├── style.css
# └── app.js
记忆口诀: 有斜杠传内容,无斜杠传目录。
多源复制
# 同时同步多个源目录到目标
rsync -av /data/docs/ /data/images/ /data/videos/ /backup/all/
# 混合文件和目录
rsync -av /etc/hosts /etc/passwd /home/user/ /backup/config/
本地备份示例
# 备份用户主目录到外接硬盘
rsync -av --progress /home/user/ /mnt/external/backup/
# 备份网站目录(保留所有属性)
rsync -avz --progress /var/www/ /backup/www/
# 备份并显示统计
rsync -avh --stats /data/ /backup/data/
# 示例输出
# Number of files: 12,534
# Number of regular files transferred: 234
# Total file size: 5.67G
# Total transferred file size: 234.56M
# File list size: 245,678
# File list generation time: 0.001 seconds
# Total bytes sent: 123,456,789
# Total bytes received: 567
# sent 123,456,789 received 567 12.34M bytes/sec
# total size is 5.67G speedup is 45.67
4. 远程同步(通过 SSH)
从本地推送到远程(Upload)
# 基本上传
rsync -avz ./local-dir/ user@remote:/remote/dir/
# 示例
rsync -avz ./project/ deploy@192.168.1.100:/opt/project/
# 指定 SSH 端口
rsync -avz -e "ssh -p 2222" ./project/ deploy@192.168.1.100:/opt/project/
# 指定 SSH 密钥
rsync -avz -e "ssh -i ~/.ssh/deploy_key" ./project/ deploy@192.168.1.100:/opt/project/
# 同时指定端口和密钥
rsync -avz -e "ssh -p 2222 -i ~/.ssh/deploy_key" ./project/ deploy@192.168.1.100:/opt/project/
# 显示进度
rsync -avzP ./project/ deploy@192.168.1.100:/opt/project/
# -P = --partial --progress
从远程拉取到本地(Download)
# 基本下载
rsync -avz user@remote:/remote/dir/ ./local-dir/
# 示例
rsync -avz root@192.168.1.100:/var/log/ ./logs/
# 拉取整个目录(不包含斜杠)
rsync -avz root@192.168.1.100:/var/log ./logs/
使用 SSH 配置文件中的别名
# 如果 ~/.ssh/config 中定义了
Host myserver
HostName 192.168.1.100
User deploy
Port 2222
IdentityFile ~/.ssh/deploy_key
# 直接使用别名
rsync -avz ./project/ myserver:/opt/project/
rsync -avz myserver:/var/log/ ./logs/
通过跳板机同步
# 通过跳板机(使用 ProxyJump)
rsync -avz -e "ssh -J admin@bastion.example.com" ./data/ deploy@10.0.0.100:/data/
# 通过跳板机(使用 ProxyCommand)
rsync -avz -e "ssh -o ProxyCommand='ssh admin@bastion -W %h:%p'" ./data/ deploy@10.0.0.100:/data/
远程同步示例输出
sending incremental file list
./
index.html
1,234 100% 12.00kB/s 0:00:00
style.css
45,678 100% 448.02kB/s 0:00:00
app.js
234,567 100% 2.24MB/s 0:00:00
sent 281,479 bytes received 72 bytes 624,667.56 bytes/sec
total size is 281,479 speedup is 1.00
应用场景:
- 代码部署到生产服务器
- 日志文件收集
- 配置文件分发
- 网站数据迁移
5. rsync 守护进程模式
服务端配置
# /etc/rsyncd.conf
uid = nobody
gid = nobody
use chroot = yes
max connections = 10
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
[backup]
path = /data/backup
comment = Backup Directory
read only = no
list = yes
uid = root
gid = root
auth users = backupuser
secrets file = /etc/rsyncd.secrets
hosts allow = 192.168.1.0/24
hosts deny = *
[data]
path = /data/share
comment = Shared Data
read only = yes
list = yes
hosts allow = 192.168.1.0/24
密码文件
# /etc/rsyncd.secrets
backupuser:mysecretpassword
# 设置权限(必须!)
chmod 600 /etc/rsyncd.secrets
启动守护进程
# 以守护进程模式启动
rsync --daemon
# 通过 systemd 管理
systemctl enable rsync
systemctl start rsync
# 确认监听
ss -tlnp | grep 873
客户端连接
# 列出服务端的模块
rsync rsync://backupuser@192.168.1.100/
# 从服务端拉取
rsync -avz backupuser@192.168.1.100::backup/ /local/backup/
# 推送到服务端
rsync -avz /local/data/ backupuser@192.168.1.100::backup/data/
# 使用密码文件(避免交互输入)
echo "mysecretpassword" > ~/.rsync.pass
chmod 600 ~/.rsync.pass
rsync -avz --password-file=~/.rsync.pass /local/data/ backupuser@192.168.1.100::backup/
# 指定端口(默认 873)
rsync -avz --port=8730 backupuser@192.168.1.100::backup/ /local/
守护进程 vs SSH 模式对比
| 特性 | SSH 模式 | 守护进程模式 |
|---|---|---|
| 认证 | SSH 密钥/密码 | rsync 用户名/密码 |
| 加密 | ✅ 全程加密 | ❌ 明文传输 |
| 性能 | 有 SSH 开销 | 更快 |
| 配置 | 无需服务端配置 | 需要 rsyncd.conf |
| 端口 | 22 | 873 |
| 安全性 | 高 | 中(建议仅内网) |
| 推荐场景 | 公网传输 | 内网高性能传输 |
应用场景: 大规模内网文件分发、NAS 备份、匿名文件下载服务。
6. 增量备份策略
6.1 --link-dest 硬链接增量备份
# 创建带日期的增量备份
rsync -av --link-dest=/backup/daily-2026-07-26/ \
/data/ /backup/daily-2026-07-27/
# 工作原理:
# 1. 对比源和上一次备份(link-dest)
# 2. 未变化的文件通过硬链接指向旧备份(不占额外空间)
# 3. 仅真正变化的文件被传输和存储
# 目录结构
# /backup/
# ├── daily-2026-07-25/ (完整备份)
# ├── daily-2026-07-26/ (增量,大部分是硬链接)
# └── daily-2026-07-27/ (增量,大部分是硬链接)
6.2 自动化每日增量备份脚本
#!/bin/bash
# backup-daily.sh
SOURCE="/data/"
BACKUP_DIR="/backup"
DATE=$(date +%Y-%m-%d)
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
# 创建日志目录
mkdir -p "$BACKUP_DIR"
# 执行增量备份
rsync -av --delete \
--link-dest="$BACKUP_DIR/daily-$YESTERDAY/" \
"$SOURCE" \
"$BACKUP_DIR/daily-$DATE/" \
2>&1 | tee "$BACKUP_DIR/backup-$DATE.log"
# 清理超过 30 天的备份
find "$BACKUP_DIR" -maxdepth 1 -type d -name "daily-*" -mtime +30 -exec rm -rf {} \;
echo "备份完成: $DATE"
6.3 使用 --backup 保留变更历史
# 传输时,如果目标文件被覆盖,先将旧文件备份
rsync -avb --backup-dir=/backup/changed-$(date +%Y-%m-%d) \
/data/ /backup/current/
# 参数说明
# -b: 启用备份模式
# --backup-dir: 被覆盖的文件存放目录
# 默认备份后缀是 ~,可用 --suffix 自定义
# 自定义后缀
rsync -avb --suffix=.bak-$(date +%Y%m%d) /data/ /backup/current/
6.4 完整备份+增量备份策略
#!/bin/bash
# 完整备份脚本 (每周日运行)
# weekly-full-backup.sh
SOURCE="/data/"
BACKUP_BASE="/backup"
DATE=$(date +%Y-%m-%d)
WEEK=$(date +%Y-W%V)
rsync -av --delete \
--link-dest="$BACKUP_BASE/current/" \
"$SOURCE" \
"$BACKUP_BASE/full-$DATE/" \
--stats 2>&1 | tee "$BACKUP_BASE/full-$DATE.log"
# 更新 current 链接
rm -f "$BACKUP_BASE/current"
ln -s "$BACKUP_BASE/full-$DATE" "$BACKUP_BASE/current"
echo "完整备份完成: $DATE"
#!/bin/bash
# 增量备份脚本 (周一到周六运行)
# daily-incremental-backup.sh
SOURCE="/data/"
BACKUP_BASE="/backup"
DATE=$(date +%Y-%m-%d)
rsync -av --delete \
--link-dest="$BACKUP_BASE/current/" \
"$SOURCE" \
"$BACKUP_BASE/incr-$DATE/" \
--stats 2>&1 | tee "$BACKUP_BASE/incr-$DATE.log"
echo "增量备份完成: $DATE"
备份方案对比
| 方案 | 命令 | 优点 | 缺点 |
|---|---|---|---|
| 完整备份 | rsync -av /data/ /backup/ |
简单、恢复快 | 耗时、占空间 |
| 硬链接增量 | rsync -av --link-dest=... |
节省空间、每个备份独立完整 | 需要 Linux 硬链接支持 |
| --backup 模式 | rsync -avb --backup-dir=... |
保留变更历史 | 管理复杂 |
| 混合策略 | 完整 + 增量 | 平衡空间和时间 | 需要脚本管理 |
应用场景: 每日数据备份、网站备份、数据库备份文件归档、多版本保留。
7. 过滤与排除规则
7.1 --exclude 排除文件
# 排除单个模式
rsync -av --exclude='*.tmp' /data/ /backup/
# 排除多个模式
rsync -av \
--exclude='*.tmp' \
--exclude='*.log' \
--exclude='.git' \
--exclude='node_modules' \
/project/ /backup/project/
# 排除目录
rsync -av --exclude='cache/' /data/ /backup/
# 排除隐藏文件
rsync -av --exclude='.*' /data/ /backup/
# 使用通配符
rsync -av --exclude='*.log.[0-9][0-9]' /data/ /backup/
7.2 --include 和 --exclude 结合使用
# 只传输 .jpg 和 .png 文件,排除其他所有
rsync -av \
--include='*/' \
--include='*.jpg' \
--include='*.png' \
--exclude='*' \
/photos/ /backup/photos/
# 规则解释:
# --include='*/' 先包含所有目录(这样才能进入子目录)
# --include='*.jpg' 包含 jpg 文件
# --include='*.png' 包含 png 文件
# --exclude='*' 排除其他所有文件
# ⚠️ 顺序很重要!rsync 按顺序匹配,第一个匹配的规则生效
7.3 --exclude-from 从文件读取排除规则
# 创建排除规则文件
cat > /path/to/exclude-list.txt << 'EOF'
# 注释行
*.tmp
*.log
*.bak
*.swp
.DS_Store
node_modules/
.git/
.svn/
__pycache__/
*.pyc
.cache/
tmp/
*.tar.gz
*.zip
EOF
# 使用排除文件
rsync -av --exclude-from='/path/to/exclude-list.txt' /data/ /backup/
7.4 --include-from 从文件读取包含规则
# 创建包含规则文件
cat > /path/to/include-list.txt << 'EOF'
*/
*.conf
*.cfg
*.json
*.yaml
*.yml
EOF
# 只同步配置文件
rsync -av \
--include-from='/path/to/include-list.txt' \
--exclude='*' \
/etc/ /backup/etc-configs/
7.5 过滤规则语法详解
# 规则模式说明
# 1. 简单文件名匹配
*.tmp # 匹配所有 .tmp 结尾的文件
# 2. 路径匹配(以 / 开头表示相对根路径)
/cache/ # 只排除顶层的 cache 目录
/cache # 匹配根目录下名为 cache 的文件或目录
# 3. 通配符
*.log # 任意目录中的 .log 文件
foo*.txt # 以 foo 开头的 txt 文件
data[0-9].csv # data0.csv, data1.csv, ... data9.csv
# 4. 以 / 结尾只匹配目录
build/ # 排除所有名为 build 的目录
/cache/ # 只排除顶层的 cache 目录
# 5. ** 匹配任意路径深度
**/temp/ # 任意深度的 temp 目录
data/**/cache/ # data 下任意深度的 cache 目录
# 6. 锚定路径(以 / 开头)
/var/cache/*.tmp # 精确路径匹配
过滤规则应用场景
# 场景 1:部署 Node.js 项目(排除依赖和源码)
rsync -av --delete \
--exclude='node_modules/' \
--exclude='.git/' \
--exclude='src/' \
--exclude='test/' \
--exclude='*.md' \
./project/ deploy@server:/opt/project/
# 场景 2:备份 Python 项目(排除缓存和虚拟环境)
rsync -av \
--exclude='__pycache__/' \
--exclude='*.pyc' \
--exclude='.venv/' \
--exclude='venv/' \
--exclude='.env' \
./project/ /backup/project/
# 场景 3:只备份图片和视频
rsync -av \
--include='*/' \
--include='*.jpg' \
--include='*.png' \
--include='*.mp4' \
--include='*.mov' \
--exclude='*' \
/data/ /backup/media/
# 场景 4:排除大文件
rsync -av --max-size='10M' /data/ /backup/
# 场景 5:只传输今天修改的文件
rsync -av --files-from=<(find /data -mtime -1 -type f) / /backup/
8. 删除与镜像同步
--delete 详解
# 镜像同步:目标完全匹配源
rsync -av --delete /source/ /backup/
# 工作原理:
# 源有 3 个文件:a.txt, b.txt, c.txt
# 目标有 4 个文件:a.txt, b.txt, d.txt, e.txt
# 同步后目标:a.txt, b.txt, c.txt(d.txt 和 e.txt 被删除)
--delete 的子选项
# --delete-before: 传输前先删除(更安全,需要更多磁盘空间)
rsync -av --delete --delete-before /source/ /backup/
# --delete-during: 传输过程中删除(默认行为)
rsync -av --delete /source/ /backup/
# --delete-after: 传输完成后再删除(适合大量删除)
rsync -av --delete --delete-after /source/ /backup/
# --delete-delay: 延迟到传输结束后批量删除(适合大量文件)
rsync -av --delete --delete-delay /source/ /backup/
保护文件不被删除
# --delete 但排除特定文件不删除
rsync -av --delete \
--filter='protect *.important' \
/source/ /backup/
# 或者使用 --delete-excluded(连同 excluded 文件一起删除)
rsync -av --delete --delete-excluded \
--exclude='*.tmp' \
/source/ /backup/
限制删除数量
# 最多删除 100 个文件(防止误删大量文件)
rsync -av --delete --max-delete=100 /source/ /backup/
# 完全不删除任何文件
rsync -av /source/ /backup/
安全删除:先预览
# 第一步:先 dry-run 看看会删什么
rsync -av --delete --dry-run /source/ /backup/
# 输出中 "deleting" 开头的行就是将被删除的文件
# 仔细检查这些文件
# 第二步:确认无误后实际执行
rsync -av --delete /source/ /backup/
--update 模式(不覆盖更新的文件)
# 如果目标文件比源文件新,则跳过
rsync -avu /source/ /backup/
# -u = --update
# 应用场景:双向同步的第一步
--existing 和 --ignore-existing
# 只更新目标中已存在的文件(不传输新文件)
rsync -av --existing /source/ /backup/
# 只传输新文件(不更新已存在的文件)
rsync -av --ignore-existing /source/ /backup/
应用场景:
--existing:只更新配置文件,不传输新增文件--ignore-existing:只增量添加新文件,不修改旧文件(归档场景)
9. 高级传输控制
9.1 断点续传
# --partial:保留传输了部分的文件
# 下次运行时从断点继续
rsync -avP /large-file.iso /backup/
# -P = --partial --progress
# 如果传输被中断:
# sending incremental file list
# large-file.iso
# 345,678,901 45% 12.34MB/s 0:00:45
# (中断)
# 重新运行:
rsync -avP /large-file.iso /backup/
# 从 45% 继续!
# 指定断点续传文件存放目录
rsync -av --partial --partial-dir=.rsync-partial /data/ /backup/
9.2 带宽限制
# 限制传输速率为 1MB/s
rsync -av --bwlimit=1000 /data/ /backup/
# 单位是 KB/s,1000 = ~1MB/s
# 在工作时间限速,下班全速
HOUR=$(date +%H)
if [ "$HOUR" -ge 9 ] && [ "$HOUR" -lt 18 ]; then
BWLIMIT="2000" # 工作时间 2MB/s
else
BWLIMIT="0" # 下班不限速
fi
rsync -av --bwlimit=$BWLIMIT /data/ /backup/
# 限速参数说明
# --bwlimit=0 无限制(默认)
# --bwlimit=500 500 KB/s
# --bwlimit=1024 1 MB/s
# --bwlimit=10240 10 MB/s
9.3 文件大小过滤
# 只传输小于 10MB 的文件
rsync -av --max-size='10M' /data/ /backup/
# 只传输大于 1KB 的文件
rsync -av --min-size='1K' /data/ /backup/
# 大小范围
rsync -av --min-size='1K' --max-size='100M' /data/ /backup/
# 支持的单位
# K, KB = Kilobyte
# M, MB = Megabyte
# G, GB = Gigabyte
# T, TB = Terabyte
9.4 --remove-source-files(传输后删除源文件)
# 传输完成后删除源文件(类似 mv)
rsync -av --remove-source-files /data/inbox/ /data/archive/
# ⚠️ 注意:只删除文件,不删除目录
# 如需删除空目录:
find /data/inbox/ -type d -empty -delete
9.5 延迟更新(原子性替换)
# 所有文件先传输到临时目录,最后一次性替换
rsync -av --delay-updates /data/ /backup/
# 更安全:先传到临时目录,完成后替换
rsync -av --delay-updates --partial-dir=.rsync-tmp /data/ /backup/
9.6 压缩与加密
# 基本压缩
rsync -avz /data/ user@remote:/backup/
# 指定压缩级别(rsync 3.2.0+)
rsync -avz --compress-choice=zstd --compress-level=3 /data/ user@remote:/backup/
# 压缩算法选择
# --compress-choice=zstd # 最快,推荐
# --compress-choice=lz4 # 最快,压缩率低
# --compress-choice=zlib # 兼容性好
# --compress-choice=none # 不压缩(已压缩文件如 .mp4, .zip)
9.7 --checksum 强制校验
# 默认用文件大小+修改时间判断文件是否变化
# --checksum 使用 MD5 校验和判断(更准确但更慢)
rsync -avc /data/ /backup/
# 适用场景:
# - 文件内容变了但大小和修改时间没变
# - 备份后校验数据完整性
# - 怀疑文件损坏
9.8 批量传输模式
# 生成批量文件列表
rsync -av --write-batch=backup-batch /data/ /backup/
# 在目标机器上执行批量传输
rsync -av --read-batch=backup-batch /backup/
# 应用场景:
# - 离线传输(先生成差异文件,再传到目标执行)
# - 批量部署到多台服务器
# - 网络不稳定环境
10. rsync 与 find 结合
只传输特定条件的文件
# 只传输最近 7 天修改过的文件
rsync -av --files-from=<(find /data -mtime -7 -type f) / /backup/recent/
# 只传输特定扩展名的文件
rsync -av --files-from=<(find /data -name "*.conf" -type f) / /backup/confs/
# 只传输特定大小的文件
rsync -av --files-from=<(find /data -size +1M -size -100M -type f) / /backup/medium-files/
# 只传输空目录
rsync -av --files-from=<(find /data -type d -empty) / /backup/empty-dirs/
# 组合条件
rsync -av --files-from=<(find /data -name "*.log" -mtime -1 -size +1k -type f) / /backup/recent-logs/
传输文件列表
# 从文件列表传输
find /data -name "*.jpg" > /tmp/file-list.txt
rsync -av --files-from=/tmp/file-list.txt / /backup/photos/
# 使用 -0 处理含空格的文件名
find /data -name "*.jpg" -print0 > /tmp/file-list.txt
rsync -av -0 --files-from=/tmp/file-list.txt / /backup/photos/
# 或者直接管道
find /data -name "*.conf" -print0 | rsync -av -0 --files-from=- / /backup/confs/
0 字节分隔符处理特殊文件名
# 处理文件名中的空格、换行等特殊字符
find /data -type f -print0 | rsync -av --from0 --files-from=- / /backup/
11. 自动化备份脚本
11.1 完整的日常备份脚本
#!/bin/bash
# daily-backup.sh — 完整的日常备份脚本
# 推荐加入 crontab 每日运行
set -euo pipefail
# ===== 配置 =====
SOURCE_DIR="/data"
BACKUP_DIR="/backup"
REMOTE_USER="backup"
REMOTE_HOST="192.168.1.200"
REMOTE_DIR="/backup/server-1"
LOG_FILE="/var/log/rsync-backup.log"
EXCLUDE_FILE="/etc/rsync-backup-exclude.txt"
RETENTION_DAYS=30
SSH_PORT=22
SSH_KEY="/root/.ssh/backup_key"
MAX_BWLIMIT=5000
# ===== 初始化 =====
DATE=$(date +%Y-%m-%d)
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
LOCAL_BACKUP="$BACKUP_DIR/$DATE"
log() {
echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE"
}
# ===== 执行备份 =====
log "===== 开始备份 ====="
log "源: $SOURCE_DIR"
log "本地目标: $LOCAL_BACKUP"
log "远程目标: $REMOTE_HOST:$REMOTE_DIR"
# 本地备份(带硬链接增量)
if [ -d "$BACKUP_DIR/$(date -d yesterday +%Y-%m-%d)" ]; then
LINK_DEST="--link-dest=$BACKUP_DIR/$(date -d yesterday +%Y-%m-%d)"
else
LINK_DEST=""
fi
rsync -av --delete \
$LINK_DEST \
--exclude-from="$EXCLUDE_FILE" \
--stats \
--bwlimit=$MAX_BWLIMIT \
"$SOURCE_DIR/" \
"$LOCAL_BACKUP/" \
2>&1 | tee -a "$LOG_FILE"
log "本地备份完成"
# 远程备份
rsync -avz --delete \
--exclude-from="$EXCLUDE_FILE" \
--bwlimit=$MAX_BWLIMIT \
-e "ssh -p $SSH_PORT -i $SSH_KEY" \
"$SOURCE_DIR/" \
"$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" \
2>&1 | tee -a "$LOG_FILE"
log "远程备份完成"
# 清理过期备份
log "清理超过 $RETENTION_DAYS 天的备份..."
find "$BACKUP_DIR" -maxdepth 1 -type d -name "20??-??-??" -mtime +$RETENTION_DAYS -exec rm -rf {} \;
log "===== 备份全部完成 ====="
11.2 多服务器同步部署脚本
#!/bin/bash
# deploy-to-all.sh — 批量部署到多台服务器
SERVERS=("web-01:192.168.1.101" "web-02:192.168.1.102" "web-03:192.168.1.103")
USER="deploy"
SOURCE="./dist/"
REMOTE_PATH="/var/www/app/"
SSH_PORT=2222
for server_info in "${SERVERS[@]}"; do
NAME=$(echo "$server_info" | cut -d: -f1)
HOST=$(echo "$server_info" | cut -d: -f2)
echo "===== 部署到 $NAME ($HOST) ====="
rsync -avz --delete \
--exclude='.git/' \
--exclude='node_modules/' \
--exclude='.env.local' \
--stats \
-e "ssh -p $SSH_PORT" \
"$SOURCE" \
"$USER@$HOST:$REMOTE_PATH"
if [ $? -eq 0 ]; then
echo "✅ $NAME 部署成功"
else
echo "❌ $NAME 部署失败"
fi
done
echo "===== 全部部署完成 ====="
11.3 数据库备份传输脚本
#!/bin/bash
# db-backup-transfer.sh — 数据库备份并传输到备份服务器
DB_HOST="localhost"
DB_USER="backup_user"
DB_PASS="backup_password"
BACKUP_DIR="/tmp/db-backups"
REMOTE="backup@192.168.1.200:/backup/databases/"
SSH_KEY="/root/.ssh/backup_key"
DATE=$(date +%Y-%m-%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
# 导出所有数据库
DATABASES=$(mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" -e "SHOW DATABASES;" | grep -v Database | grep -v information_schema | grep -v performance_schema)
for db in $DATABASES; do
echo "导出: $db"
mysqldump -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" \
--single-transaction --routines --triggers \
"$db" | gzip > "$BACKUP_DIR/${db}_${DATE}.sql.gz"
done
# 传输到备份服务器
rsync -avz --partial \
--remove-source-files \
--bwlimit=2000 \
-e "ssh -i $SSH_KEY" \
"$BACKUP_DIR/" \
"$REMOTE"
# 清理空目录
find "$BACKUP_DIR" -type f -empty -delete
echo "数据库备份传输完成"
11.4 Crontab 定时任务配置
# 编辑 crontab
crontab -e
# 每日凌晨 2 点完整备份
0 2 * * * /opt/scripts/daily-backup.sh >> /var/log/backup-cron.log 2>&1
# 每周日凌晨 1 点完整备份(级别更高)
0 1 * * 0 /opt/scripts/weekly-full-backup.sh >> /var/log/backup-cron.log 2>&1
# 每天 6 点到 22 点,每小时增量同步
0 6-22 * * * /opt/scripts/hourly-sync.sh >> /var/log/sync-cron.log 2>&1
# 每 15 分钟同步一次关键数据
*/15 * * * * rsync -aq --delete /data/critical/ backup@nas:/backup/critical/ >> /var/log/critical-sync.log 2>&1
12. rsync 在 Windows 上的使用
使用 WSL(Windows Subsystem for Linux)
# 在 WSL 中直接使用 rsync
wsl rsync -avz /mnt/c/Users/yourname/Documents/ user@server:/backup/docs/
使用 cwRsync / Git Bash
# cwRsync 安装后可以直接在 cmd 中使用
rsync -avz -e "ssh -i C:\Users\yourname\.ssh\id_rsa" /cygdrive/c/Users/yourname/Documents/ user@server:/backup/
# Git Bash 中使用
rsync -avz -e ssh /c/Users/yourname/Documents/ user@server:/backup/
Windows 路径映射
| Windows 路径 | rsync/cygwin 路径 |
|---|---|
C:\Users\... |
/cygdrive/c/Users/... 或 /c/Users/... |
D:\Data\... |
/cygdrive/d/Data/... 或 /d/Data/... |
13. 性能优化
13.1 关键性能参数
# 禁用增量算法,直接传输整个文件
# 适用于:本地同步、高速网络、文件大部分都变化了
rsync -avW /data/ /backup/
# 调整 I/O 缓冲区大小
rsync -av --block-size=8192 /data/ /backup/
# 限制 CPU 使用(降低压缩级别)
rsync -avz --compress-level=1 /data/ user@remote:/backup/
# 并行传输多个文件(使用 xargs)
echo -e "dir1\ndir2\ndir3" | xargs -P 3 -I {} rsync -av /data/{}/ user@remote:/backup/{}
# -P 3 表示 3 个并行 rsync 进程
13.2 使用 parallel rsync 加速
# 方法 1:GNU Parallel + rsync
find /data -maxdepth 1 -type d | tail -n +2 | \
parallel -j 4 rsync -av {} user@remote:/backup/
# 方法 2:xargs 并行
ls /data/ | xargs -P 4 -I {} rsync -av /data/{} user@remote:/backup/{}
# 方法 3:fpsync(基于 fpart)
fpsync -n 4 /data/ user@remote:/backup/
13.3 网络优化
# 使用更快的加密算法
rsync -avz -e "ssh -c aes128-gcm@openssh.com" /data/ user@remote:/backup/
# 使用最快的压缩算法
rsync -avz --compress-choice=zstd /data/ user@remote:/backup/
# 使用 SSH 多路复用(避免重复连接)
# ~/.ssh/config
Host backup-server
HostName 192.168.1.200
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist yes
# 然后多次 rsync 调用会复用 SSH 连接
rsync -av /data/dir1/ backup-server:/backup/dir1/
rsync -av /data/dir2/ backup-server:/backup/dir2/
13.4 大量文件优化
# 当文件数极多时(百万级),避免一次性生成完整文件列表
# 使用 --fuzzy 自动寻找增量文件
rsync -avy --fuzzy /data/ /backup/
# 使用 --omit-dir-times 如果不需要保留目录时间
rsync -av --omit-dir-times /data/ /backup/
# 如果不需要保留权限(加快速度)
rsync -rtv /data/ /backup/ # 只保留修改时间和递归
13.5 性能对比参考
| 场景 | 推荐参数 | 说明 |
|---|---|---|
| 本地 SSD → SSD | -avW |
禁用增量算法,全文件传输更快 |
| 慢速网络 | -avz --compress-choice=zstd |
最大压缩 |
| 高速局域网 | -avW --compress-choice=none |
不压缩,减少 CPU 开销 |
| 海量小文件 | -av --compress-choice=none |
不压缩(CPU 瓶颈) |
| 大文件少 | -avz --partial --inplace |
增量+就地更新 |
| 公网传输 | -avz -e "ssh -c aes128-gcm" |
快速加密 + 压缩 |
14. 故障排查
常见错误及解决
权限被拒绝
# 检查源文件读权限
ls -la /data/
# 检查目标目录写权限
ls -la /backup/
# 检查 SSH 密钥
ssh -i ~/.ssh/key user@host "echo ok"
# 远程 rsync 权限
ssh user@host "which rsync && rsync --version"
"failed: No space left on device"
# 检查目标磁盘空间
df -h /backup/
# 检查源数据大小
du -sh /data/
# 清理后重试
# 或使用 --max-size 分批传输
"argument list too long"
# 文件太多超出参数限制
# 使用 --files-from 代替命令行参数
find /data -type f > /tmp/filelist.txt
rsync -av --files-from=/tmp/filelist.txt / /backup/
# 或使用 -0 处理大量文件
find /data -type f -print0 | rsync -av -0 --files-from=- / /backup/
连接超时
# 指定超时时间
rsync -av --timeout=300 /data/ user@remote:/backup/
# 使用 --contimeout 指定连接超时
rsync -av --contimeout=30 /data/ user@remote:/backup/
部分文件传输失败
# 使用 --ignore-errors 忽略错误继续传输
rsync -av --ignore-errors /data/ /backup/
# 使用 --partial 保留已传输部分
rsync -av --partial /data/ /backup/
# 重新传输失败的单个文件
rsync -av /data/failing-file.txt /backup/
调试模式
# 增加详细级别
rsync -avvv /data/ /backup/ # 调试级别 1
rsync -avvvv /data/ /backup/ # 调试级别 2
# 使用 --msgs2stderr 将调试信息输出到 stderr
rsync -av --msgs2stderr /data/ user@remote:/backup/
# 检查将传输哪些文件(不实际传输)
rsync -av --dry-run --stats /data/ /backup/
验证备份完整性
# 传输后校验
rsync -avc /data/ /backup/
# -c 使用校验和验证
# 手动校验(MD5 对比)
find /data -type f -exec md5sum {} \; | sort > /tmp/source.md5
find /backup -type f -exec md5sum {} \; | sort > /tmp/target.md5
diff /tmp/source.md5 /tmp/target.md5
# 如果输出为空,说明完全一致
# 快速校验(文件数量和总大小)
echo "源:"; find /data -type f | wc -l; du -sb /data
echo "目标:"; find /backup -type f | wc -l; du -sb /backup
15. 常用速查表
参数速查
| 参数 | 说明 | 最常用场景 |
|---|---|---|
-a |
归档模式 | ✅ 几乎总是用 |
-v |
详细输出 | ✅ 几乎总是用 |
-z |
压缩传输 | 远程传输 |
-P |
进度+断点续传 | 大文件传输 |
-n |
模拟运行 | 执行前预览 |
--delete |
删除多余文件 | 镜像同步 |
-c |
校验和验证 | 数据完整性校验 |
-W |
全文件传输 | 本地同步/高速网络 |
-u |
不覆盖更新文件 | 双向同步 |
--exclude |
排除文件 | 跳过临时文件 |
--partial |
断点续传 | 大文件传输 |
--bwlimit |
限速 | 生产环境保护带宽 |
--link-dest |
硬链接增量 | 备份方案 |
--max-size |
最大文件限制 | 按大小过滤 |
--remove-source-files |
传输后删源 | 移动文件 |
-e |
远程 Shell | 指定 SSH 选项 |
最常用命令组合
# 1. 日常同步(最常用)
rsync -avz --delete --exclude='.git' ./project/ deploy@server:/opt/project/
# 2. 安全镜像同步(先预览)
rsync -avn --delete /data/ /backup/ # 预览
rsync -av --delete /data/ /backup/ # 执行
# 3. 大文件传输(断点续传)
rsync -avP --partial /large-file.iso user@server:/backup/
# 4. 增量备份
rsync -av --link-dest=/backup/yesterday/ /data/ /backup/today/
# 5. 通过跳板机
rsync -avz -e "ssh -J admin@bastion" /data/ deploy@10.0.0.100:/backup/
# 6. 限速传输
rsync -avz --bwlimit=2000 /data/ user@remote:/backup/
# 7. 只传输特定类型文件
rsync -av --include='*.conf' --include='*/' --exclude='*' /etc/ /backup/confs/
# 8. 收集日志
rsync -avz --max-size='100M' --include='*.log' --include='*/' --exclude='*' \
root@web-{01,02,03}:/var/log/ ./all-logs/
# 9. 传输后删除源文件(移动)
rsync -av --remove-source-files /data/inbox/ /data/archive/
# 10. 每日备份(crontab)
0 2 * * * rsync -aq --delete --link-dest=/backup/$(date -d yesterday +\%Y-\%m-\%d)/ \
/data/ /backup/$(date +\%Y-\%m-\%d)/
rsync 参数与 scp 对比
| 操作 | scp | rsync |
|---|---|---|
| 单文件上传 | scp file user@host:/path/ |
rsync -av file user@host:/path/ |
| 单文件下载 | scp user@host:/path/file . |
rsync -av user@host:/path/file . |
| 目录上传 | scp -r dir/ user@host:/path/ |
rsync -av dir/ user@host:/path/ |
| 目录下载 | scp -r user@host:/path/dir/ . |
rsync -av user@host:/path/dir/ . |
| 指定端口 | scp -P 2222 ... |
rsync -e "ssh -p 2222" ... |
| 指定密钥 | scp -i ~/.ssh/key ... |
rsync -e "ssh -i ~/.ssh/key" ... |
| 压缩 | scp -C ... |
rsync -avz ... |
总结
rsync 的核心优势在于 高效增量传输 + 灵活控制。掌握以下能力即可应对所有场景:
- 基本同步 —
-avz三剑客 - 镜像同步 —
--delete保持目标与源完全一致 - 排除规则 —
--exclude/--include精确控制传输内容 - 增量备份 —
--link-dest节省空间的每日备份 - 断点续传 —
-P大文件不怕中断 - 限速保护 —
--bwlimit保护生产网络 - 安全预览 —
-ndry-run 永远先看再执行
📖 推荐学习路径: 本地同步 → 远程同步 → 过滤规则 → 镜像同步 → 增量备份 → 性能优化

浙公网安备 33010602011771号