rsync命令最全用法指南

rsync(remote sync)是 Linux/Unix 下最强大的文件同步和备份工具。它采用增量传输算法,只传输文件的变化部分,因此速度极快、效率极高。本文涵盖 rsync 从基础到高级的所有用法。


目录

  1. rsync 基础概念
  2. 基本语法与核心参数
  3. 本地同步
  4. 远程同步(通过 SSH)
  5. rsync 守护进程模式
  6. 增量备份策略
  7. 过滤与排除规则
  8. 删除与镜像同步
  9. 高级传输控制
  10. rsync 与 find 结合
  11. 自动化备份脚本
  12. rsync 在 Windows 上的使用
  13. 性能优化
  14. 故障排查
  15. 常用速查表

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. 增量备份策略

# 创建带日期的增量备份
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 的核心优势在于 高效增量传输 + 灵活控制。掌握以下能力即可应对所有场景:

  1. 基本同步 — -avz 三剑客
  2. 镜像同步 — --delete 保持目标与源完全一致
  3. 排除规则 — --exclude / --include 精确控制传输内容
  4. 增量备份 — --link-dest 节省空间的每日备份
  5. 断点续传 — -P 大文件不怕中断
  6. 限速保护 — --bwlimit 保护生产网络
  7. 安全预览 — -n dry-run 永远先看再执行

📖 推荐学习路径: 本地同步 → 远程同步 → 过滤规则 → 镜像同步 → 增量备份 → 性能优化


posted @ 2026-09-29 10:36  直角漫步  阅读(105)  评论(0)    收藏  举报