Rsync 完全使用指南
目录
概述
什么是 Rsync?
Rsync(Remote Synchronization)是一个开源的文件同步和传输工具,最初由 Andrew Tridgell 和 Paul Mackerras 于1996年开发。它采用智能的增量传输算法,能够高效地在本地或远程系统间同步文件和目录。
核心特性
- 增量传输:仅传输源文件和目标文件之间的差异部分
- 完整性检查:使用校验和确保数据传输的准确性
- 保持属性:保留文件权限、时间戳、所有者等元数据
- 多种传输模式:支持本地、远程(通过SSH或rsync守护进程)传输
- 压缩传输:可选的传输时压缩以减少带宽占用
- 灵活的过滤规则:强大的包含/排除文件模式匹配
工作原理
Rsync 使用 "rsync算法" 进行快速增量文件传输:
1. 发送方将文件分割为固定大小的块
2. 为每个块生成两个校验和:一个强校验(MD5)和一个弱校验
3. 接收方检查已有文件的块校验和
4. 仅传输不匹配的块和新数据
安装与配置
各平台安装方法
Linux
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install rsync
# RHEL/CentOS/Fedora
sudo yum install rsync
# 或
sudo dnf install rsync
# Arch Linux
sudo pacman -S rsync
# 验证安装
rsync --version
macOS
# macOS 预装版本通常较旧,建议更新:
brew install rsync
# 或将新版本链接到系统路径
brew link --override rsync
Windows
# 方法1:通过 WSL(推荐)
# 启用 WSL 后,安装 Linux 发行版即可使用
# 方法2:Git for Windows
# Git Bash 中自带 rsync
# 方法3:Cygwin
# 安装时选择 rsync 包
# 方法4:直接安装 cwRsync
# 商业版本,提供Windows原生支持
Rsync 守护进程配置(可选)
服务端配置
# 1. 编辑配置文件
sudo nano /etc/rsyncd.conf
# 示例配置
uid = nobody
gid = nobody
use chroot = yes
max connections = 4
pid file = /var/run/rsyncd.pid
log file = /var/log/rsync.log
[backup]
path = /data/backup
comment = Backup Area
read only = no
list = yes
auth users = backupuser
secrets file = /etc/rsyncd.secrets
# 2. 创建密码文件
sudo nano /etc/rsyncd.secrets
# 格式:username:password
backupuser:securepassword123
# 3. 设置权限
sudo chmod 600 /etc/rsyncd.secrets
# 4. 启动服务
sudo systemctl start rsync
sudo systemctl enable rsync
基本语法与选项
命令语法
rsync [选项] 源路径 目标路径
常用选项详解
基本选项
| 选项 |
说明 |
示例 |
-v, --verbose |
详细输出 |
rsync -v source dest |
-q, --quiet |
静默模式 |
rsync -q source dest |
-n, --dry-run |
试运行,不实际执行 |
rsync -n source dest |
-h, --human-readable |
人类可读格式输出 |
rsync -h source dest |
复制选项
| 选项 |
说明 |
等效组合 |
-a, --archive |
归档模式(递归+保留所有属性) |
-rlptgoD |
-r, --recursive |
递归复制目录 |
|
-l, --links |
保留符号链接 |
|
-p, --perms |
保留权限 |
|
-t, --times |
保留修改时间 |
|
-g, --group |
保留属组 |
|
-o, --owner |
保留属主(需要root权限) |
|
-D |
保留设备文件和特殊文件 |
|
同步选项
| 选项 |
说明 |
注意 |
--delete |
删除目标中源不存在的文件 |
谨慎使用 |
--delete-before |
传输前删除目标文件 |
|
--delete-during |
传输过程中删除(默认) |
|
--delete-after |
传输后删除 |
更安全 |
--ignore-existing |
跳过目标已存在的文件 |
|
--update |
仅更新比源旧的文件 |
|
过滤选项
| 选项 |
说明 |
示例 |
--exclude=PATTERN |
排除匹配模式的文件 |
--exclude='*.tmp' |
--include=PATTERN |
包含匹配模式的文件 |
--include='*.txt' |
--exclude-from=FILE |
从文件读取排除模式 |
--exclude-from=exclude.txt |
--include-from=FILE |
从文件读取包含模式 |
|
-C, --cvs-exclude |
排除CVS自动忽略的文件 |
|
传输选项
| 选项 |
说明 |
示例 |
-z, --compress |
传输时压缩 |
rsync -z source dest |
--compress-level=NUM |
压缩级别(1-9) |
--compress-level=6 |
--partial |
保留部分传输的文件 |
断点续传 |
--progress |
显示传输进度 |
|
-P |
--partial --progress 组合 |
rsync -P source dest |
--bwlimit=RATE |
限制带宽(KB/s) |
--bwlimit=1000 |
远程选项
| 选项 |
说明 |
示例 |
-e, --rsh=COMMAND |
指定远程shell |
-e ssh |
--rsync-path=PROGRAM |
指定远程rsync路径 |
--rsync-path=/usr/local/bin/rsync |
--port=PORT |
指定SSH/rsync端口 |
--port=2222 |
路径格式说明
# 本地路径
/path/to/local/dir
/path/to/local/file
# 远程路径(通过SSH)
user@host:/path/to/remote/dir
user@host:/path/to/remote/file
# 远程路径(通过rsync守护进程)
host::module/path
user@host::module/path
rsync://host:port/module/path
# 重要:目录斜杠的区别
source/ # 复制目录内容到目标
source # 复制整个目录到目标
使用场景与示例
1. 本地文件同步
基本备份
# 备份目录到另一个位置
rsync -av ~/Documents/ /mnt/backup/Documents/
# 验证备份
diff -r ~/Documents/ /mnt/backup/Documents/
镜像同步
# 创建完全相同的镜像(删除目标多余文件)
rsync -av --delete /source/ /destination/
# 安全版本:先试运行
rsync -avn --delete /source/ /destination/
大文件同步
# 使用压缩和进度显示
rsync -avzP /path/to/large/files/ /backup/large/
# 限制带宽使用(避免影响网络)
rsync -avz --bwlimit=5000 --progress /source/ /destination/
2. 远程文件传输
备份到远程服务器
# 使用SSH加密传输
rsync -avz -e ssh ~/data/ user@remote.server.com:/backup/data/
# 使用非标准SSH端口
rsync -avz -e "ssh -p 2222" ~/data/ user@remote.server.com:/backup/
# 使用SSH密钥认证(无需密码)
rsync -avz -e "ssh -i ~/.ssh/id_rsa" ~/data/ user@server:/backup/
从远程服务器拉取
# 拉取远程目录到本地
rsync -avz user@server:/remote/data/ ~/local/backup/
# 拉取并删除本地多余文件
rsync -avz --delete user@server:/remote/data/ ~/local/mirror/
服务器间同步
# 通过本地中转
rsync -avz server1:/data/ /tmp/data/
rsync -avz /tmp/data/ server2:/backup/
# 直接同步(需要双向访问权限)
ssh user@server1 "rsync -avz /data/ user@server2:/backup/"
3. 特殊场景处理
同步符号链接
# 不同处理方式对比
rsync -l source/ dest/ # 复制为符号链接
rsync -L source/ dest/ # 复制链接指向的实际文件
rsync -K source/ dest/ # 将目标符号链接视为普通目录
处理权限问题
# 保持权限(需要相应权限)
sudo rsync -av /source/ /destination/
# 不保留属主(避免权限问题)
rsync -av --no-owner --no-group source/ dest/
# 设置统一权限
rsync -av --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r source/ dest/
排除特定文件
# 多种排除方式示例
rsync -av --exclude='*.tmp' --exclude='*.log' source/ dest/
# 排除目录
rsync -av --exclude='temp/' --exclude='cache/' source/ dest/
# 使用排除文件
cat > exclude-list.txt << EOF
*.tmp
*.log
.temp/
cache/
.DS_Store
Thumbs.db
EOF
rsync -av --exclude-from='exclude-list.txt' source/ dest/
包含特定文件
# 先排除所有,再包含特定模式
rsync -av --exclude='*' --include='*.txt' --include='*.md' source/ dest/
# 包含目录结构
rsync -av --exclude='*' --include='*/' --include='*.txt' source/ dest/
4. 增量备份策略
每日增量备份
#!/bin/bash
# daily-backup.sh
SOURCE="/home/user/data/"
DEST_BASE="/mnt/backup/"
LOG_DIR="/var/log/backups"
# 创建基于日期的目录
DATE=$(date +%Y-%m-%d)
DEST="${DEST_BASE}${DATE}/"
LATEST="${DEST_BASE}latest/"
# 创建目标目录
mkdir -p "$DEST"
# 从最新备份创建硬链接,然后同步
if [ -d "$LATEST" ]; then
cp -al "$LATEST"/* "$DEST/" 2>/dev/null
fi
# 执行同步
rsync -av --delete \
--link-dest="$LATEST" \
"$SOURCE" "$DEST" \
>> "${LOG_DIR}/backup-${DATE}.log" 2>&1
# 更新最新备份链接
rm -f "$LATEST"
ln -s "$DEST" "$LATEST"
echo "备份完成: $(date)" >> "${LOG_DIR}/backup-${DATE}.log"
高级功能
1. 部分传输与恢复
# 启用部分传输(支持断点续传)
rsync --partial --progress source/ dest/
# 指定部分文件存放目录
rsync --partial-dir=.rsync-partial --progress source/ dest/
# 恢复中断的传输
rsync --append source/ dest/
2. 比较与校验
# 仅比较文件而不传输
rsync -avnc source/ dest/
# 详细比较
rsync -avn --itemize-changes source/ dest/
# 输出解释:
# >f+++++++++ 新文件
# .f..t...... 时间戳不同
# .f.s...... 大小不同
# .f.......... 文件相同
# 基于校验和的比较(更准确但更慢)
rsync -avc source/ dest/
3. 批量同步脚本
#!/bin/bash
# multi-sync.sh
CONFIG_FILE="sync-config.txt"
LOG_FILE="sync-$(date +%Y%m%d).log"
# 配置文件格式:源路径:目标路径:排除文件(可选)
# /home/user/docs:/backup/docs:exclude-docs.txt
# user@server:/data:/local/backup:exclude-server.txt
while IFS=: read -r SOURCE DEST EXCLUDE; do
echo "同步: $SOURCE -> $DEST" | tee -a "$LOG_FILE"
EXCLUDE_OPT=""
if [ -n "$EXCLUDE" ] && [ -f "$EXCLUDE" ]; then
EXCLUDE_OPT="--exclude-from=$EXCLUDE"
fi
rsync -avz --delete $EXCLUDE_OPT \
"$SOURCE" "$DEST" \
>> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "成功: $SOURCE" | tee -a "$LOG_FILE"
else
echo "失败: $SOURCE (代码: $?)" | tee -a "$LOG_FILE"
fi
echo "---" | tee -a "$LOG_FILE"
done < "$CONFIG_FILE"
4. 实时监控与同步
# 使用inotify-tools监控目录变化
#!/bin/bash
# realtime-sync.sh
SOURCE="/path/to/watch"
DEST="user@remote:/backup/"
EXCLUDE=".git/ node_modules/ *.tmp"
# 安装inotify-tools(如果需要)
# sudo apt-get install inotify-tools
inotifywait -m -r -e modify,create,delete,move "$SOURCE" |
while read -r directory events filename; do
echo "检测到变化: $events $directory$filename"
# 构建排除参数
EXCLUDE_ARGS=""
for pattern in $EXCLUDE; do
EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude='$pattern'"
done
# 执行同步
eval "rsync -avz --delete $EXCLUDE_ARGS $SOURCE $DEST"
echo "同步完成: $(date)"
done
性能优化
1. 网络优化
# 调整块大小(适合大文件)
rsync -av --block-size=8192 source/ dest/
# 禁用压缩(当CPU是瓶颈时)
rsync -av --no-compress source/ dest/
# 并行传输多个文件
# 使用parallel工具配合rsync
find /source -type f | parallel -j 4 rsync -av {} /dest/
2. 磁盘I/O优化
# 减少磁盘写入(适合SSD)
rsync -av --inplace source/ dest/
# 预分配空间(减少碎片)
rsync -av --preallocate source/ dest/
# 使用稀疏文件处理
rsync -av --sparse source/ dest/
3. 内存使用优化
# 限制内存使用
rsync -av --max-size=100M source/ dest/
# 分批处理大量小文件
find /source -type f -name "*.txt" -exec rsync -av {} /dest/ \;
故障排除
常见问题与解决方案
1. 连接问题
# 错误:ssh: connect to host xxx port 22: Connection refused
# 解决方案:
rsync -av -e "ssh -p 2222" source/ user@host:/dest/ # 指定端口
ssh -v user@host # 测试SSH连接
# 错误:rsync: connection unexpectedly closed
# 解决方案:
rsync -av --timeout=30 source/ dest/ # 增加超时时间
rsync -av --contimeout=30 source/ dest/ # 增加连接超时
2. 权限问题
# 错误:rsync: mkstemp failed: Permission denied (13)
# 解决方案:
sudo rsync -av source/ dest/ # 使用sudo
rsync -av --no-p --no-g source/ dest/ # 不保留权限
rsync -av --chmod=ugo=rwX source/ dest/ # 修改权限
# 错误:rsync: failed to set times on "/dest/file": Operation not permitted
rsync -av --no-t source/ dest/ # 不保留时间戳
3. 磁盘空间问题
# 检查可用空间
df -h /dest
# 使用试运行检查需求
rsync -avn source/ dest/ | grep "total size"
# 排除大文件
rsync -av --max-size=1G source/ dest/
4. 文件系统限制
# 处理特殊字符
rsync -av --iconv=utf-8,ascii source/ dest/
# 处理长路径
rsync -av --no-protect-args source/ dest/
调试模式
# 增加详细级别
rsync -avvv source/ dest/
# 记录详细日志
rsync -av --log-file=rsync.log --log-file-format="%i %n%L" source/ dest/
# 检查rsync协议版本
rsync --version
安全注意事项
1. 传输安全
# 始终使用SSH加密
rsync -av -e "ssh -o StrictHostKeyChecking=yes" source/ dest/
# 禁用主机密钥检查(仅测试环境)
rsync -av -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" source/ dest/
# 使用SSH密钥而非密码
ssh-keygen -t rsa -b 4096
ssh-copy-id user@host
rsync -av -e "ssh -i ~/.ssh/id_rsa" source/ user@host:/dest/
2. 认证安全
# 使用rsync守护进程时的安全配置
# /etc/rsyncd.conf 中设置:
read only = yes # 只读访问
hosts allow = 192.168.1.0/24 # IP限制
auth users = username # 需要认证
secrets file = /etc/rsyncd.secrets # 密码文件
# 密码文件权限
chmod 600 /etc/rsyncd.secrets
3. 输入验证
# 防止路径遍历攻击
# 使用chroot
use chroot = yes
# 验证源和目标路径
if [[ ! "$SOURCE" =~ ^/allowed/path/ ]]; then
echo "非法源路径"
exit 1
fi
4. 审计与监控
# 记录所有同步操作
rsync -av --log-file=/var/log/rsync/$(date +%Y%m%d).log source/ dest/
# 使用系统审计
sudo auditctl -w /usr/bin/rsync -p x
脚本自动化
1. 完整的备份脚本
#!/bin/bash
# complete-backup.sh
# 配置
SOURCE_DIRS=(
"/home/user/Documents"
"/home/user/Projects"
"/etc"
"/var/www"
)
BACKUP_ROOT="/mnt/backup"
LOG_DIR="/var/log/backups"
RETENTION_DAYS=30
EMAIL_NOTIFY="admin@example.com"
# 初始化
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="$BACKUP_ROOT/$TIMESTAMP"
LOG_FILE="$LOG_DIR/backup_$TIMESTAMP.log"
EXCLUDE_FILE="$HOME/.backup_exclude"
# 创建目录
mkdir -p "$BACKUP_DIR"
mkdir -p "$LOG_DIR"
# 开始备份
echo "=== 备份开始: $(date) ===" | tee -a "$LOG_FILE"
echo "备份目录: $BACKUP_DIR" | tee -a "$LOG_FILE"
# 备份每个目录
for SOURCE in "${SOURCE_DIRS[@]}"; do
if [ -d "$SOURCE" ]; then
DIR_NAME=$(basename "$SOURCE")
echo "备份: $SOURCE -> $BACKUP_DIR/$DIR_NAME" | tee -a "$LOG_FILE"
rsync -av --delete \
--exclude-from="$EXCLUDE_FILE" \
--link-dest="$BACKUP_ROOT/latest/$DIR_NAME" \
"$SOURCE/" "$BACKUP_DIR/$DIR_NAME/" \
>> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "成功: $SOURCE" | tee -a "$LOG_FILE"
else
echo "警告: $SOURCE 备份有问题" | tee -a "$LOG_FILE"
fi
else
echo "错误: $SOURCE 不存在" | tee -a "$LOG_FILE"
fi
done
# 创建最新备份链接
rm -f "$BACKUP_ROOT/latest"
ln -s "$BACKUP_DIR" "$BACKUP_ROOT/latest"
# 清理旧备份
find "$BACKUP_ROOT" -maxdepth 1 -type d -name "20*" -mtime +$RETENTION_DAYS \
-exec echo "删除旧备份: {}" \; \
-exec rm -rf {} \; \
>> "$LOG_FILE" 2>&1
# 发送通知
if [ -n "$EMAIL_NOTIFY" ]; then
mail -s "备份完成: $(date)" "$EMAIL_NOTIFY" < "$LOG_FILE"
fi
echo "=== 备份结束: $(date) ===" | tee -a "$LOG_FILE"
2. 配置文件管理
# .rsync-config 示例
SOURCE="user@server:/data/"
DEST="/local/backup/"
OPTIONS="-avz --delete --progress"
EXCLUDE="--exclude='*.tmp' --exclude='cache/'"
SCHEDULE="0 2 * * *" # 每天凌晨2点
# 使用配置文件的脚本
#!/bin/bash
CONFIG_FILE="$HOME/.rsync-config"
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
rsync $OPTIONS $EXCLUDE "$SOURCE" "$DEST"
else
echo "配置文件不存在: $CONFIG_FILE"
exit 1
fi
3. 系统服务配置
# /etc/systemd/system/rsync-backup.service
[Unit]
Description=Rsync Backup Service
After=network.target
[Service]
Type=oneshot
User=backupuser
ExecStart=/usr/local/bin/backup-script.sh
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/rsync-backup.timer
[Unit]
Description=Daily Rsync Backup
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
附录
A. 常用命令速查表
# 基础备份
rsync -av source/ dest/
# 远程备份
rsync -avz -e ssh local/ user@remote:/backup/
# 镜像同步
rsync -av --delete source/ dest/
# 试运行
rsync -avn source/ dest/
# 带进度和断点续传
rsync -avzP source/ dest/
# 排除文件
rsync -av --exclude='*.tmp' source/ dest/
# 带宽限制
rsync -av --bwlimit=1000 source/ dest/
B. 退出代码含义
| 代码 |
含义 |
建议操作 |
| 0 |
成功 |
无需操作 |
| 1 |
语法或用法错误 |
检查命令语法 |
| 2 |
协议不兼容 |
更新rsync版本 |
| 3 |
文件选择/IO错误 |
检查文件权限 |
| 4 |
不支持的操作 |
检查选项兼容性 |
| 5 |
协议启动失败 |
检查网络连接 |
| 10 |
socket IO错误 |
检查网络/防火墙 |
| 11 |
文件IO错误 |
检查磁盘空间/权限 |
| 12 |
协议数据流错误 |
重试传输 |
| 13 |
进程统计错误 |
检查系统资源 |
| 14 |
套接字错误 |
检查网络配置 |
| 20 |
收到SIGUSR1/SIGINT |
用户中断 |
| 21 |
等待子进程出错 |
检查系统状态 |
| 22 |
错误分配核心内存 |
检查系统内存 |
| 23 |
部分传输 |
使用--partial重试 |
| 24 |
文件 vanished |
源文件在传输中删除 |
C. 性能测试方法
# 创建测试文件
dd if=/dev/zero of=testfile bs=1M count=100
# 测试本地传输速度
time rsync -av testfile /tmp/
# 测试网络传输速度
time rsync -av testfile user@remote:/tmp/
# 测试压缩效果
rsync -avz testfile /tmp/
# 对比有/无压缩的传输时间
D. 相关工具与替代方案
- rsnapshot - 基于rsync的备份工具
- lsyncd - 实时同步守护进程
- unison - 双向同步工具
- syncthing - P2P文件同步
- rclone - 云存储同步工具
- borgbackup - 去重备份工具
E. 学习资源
- 官方文档:
man rsync
- Rsync官网:https://rsync.samba.org/
- GitHub仓库:https://github.com/WayneD/rsync
- Rsync教程:https://download.samba.org/pub/rsync/rsync.html
最后更新日期: $(date +%Y-%m-%d)
版本: 1.0
注意事项: 在实际生产环境中使用前,请务必在测试环境中验证所有命令和脚本。