WSの小屋

rsync 命令详解与实战

rsync(remote sync)是一个强大的文件同步工具,可在本地或远程系统之间高效地同步文件和目录。它只传输变化的文件部分(增量传输),大大提高了传输效率。

基本语法

rsync [选项] 源文件 目标文件

常用选项详解

选项 说明
-a, --archive 归档模式(-rlptgoD),保留权限、时间戳、软链接等所有属性
-v, --verbose 显示详细传输信息
-z, --compress 传输时压缩数据,节省带宽
-h, --human-readable 以易读格式输出数字
-P 等同 --partial --progress,显示进度条并支持断点续传
--delete 删除目标目录中源端没有的文件(保持完全同步)
-n, --dry-run 模拟运行,显示将要传输的文件,不实际执行
-e 指定远程 shell(如 SSH)
--exclude 排除匹配的文件或目录
--include 包含匹配的文件(配合 exclude 使用)
--max-size 不传输大于指定大小的文件
--bwlimit 限制传输带宽(KB/s)
--remove-source-files 传输完成后删除源文件(移动而非复制)

使用示例

1. 本地同步

# 同步目录内容(注意尾部 / 的区别)
rsync -avh /src/path/ /dest/path/    # 只同步目录内的内容
rsync -avh /src/path /dest/          # 连目录本身一起同步

# 保留软链接和权限
rsync -avh --links --perms /src/ /dest/

2. 远程同步

# 本地 → 远程
rsync -avz -e ssh /local/path/ user@remote:/remote/path/

# 远程 → 本地
rsync -avz -e ssh user@remote:/remote/path/ /local/path/

# 指定 SSH 端口
rsync -avz -e 'ssh -p 2222' /local/ user@remote:/remote/

3. 排除和包含

# 排除特定文件和目录
rsync -av --exclude='*.log' --exclude='node_modules/' --exclude='.git/' /src/ /dest/

# 使用排除规则文件
rsync -av --exclude-from='exclude.list' /src/ /dest/

# 先排除所有,再包含特定类型
rsync -av --exclude='*' --include='*.js' --include='*/' /src/ /dest/

4. 保持目录完全同步(迁移场景)

# 将源目录完整同步到目标,删除目标端多余的文件
rsync -avh --delete /src/ /dest/

# 先 dry-run 确认要删除的文件
rsync -avh --delete --dry-run /src/ /dest/

实战场景

场景一:Web 项目部署

# 只上传改动的文件,排除 node_modules
rsync -avz --delete --exclude='node_modules/' --exclude='.env' \
  ./dist/ user@server:/var/www/myapp/

场景二:定时备份脚本

配合 crontab 实现自动备份:

#!/bin/bash
# backup.sh
SOURCE="/data/www"
REMOTE="backup@backup-server:/backups/www/"
LOG="/var/log/rsync_backup.log"
DATE=$(date +%Y-%m-%d)

rsync -avz --delete \
  -e "ssh -p 22" \
  --link-dest=/backups/www_$(date -d yesterday +%Y-%m-%d) \
  $SOURCE $REMOTE \
  >> $LOG 2>&1

echo "[$DATE] Backup completed" >> $LOG
# crontab -e 每天凌晨 3 点执行
0 3 * * * /usr/local/bin/backup.sh

场景三:大文件断点续传

# 传输大文件时,如果中断可以续传
rsync -avP largefile.zip user@remote:/dest/

# 限制带宽,不影响其他网络服务
rsync -avz --bwlimit=5000 largefile.iso user@remote:/dest/

场景四:服务器迁移

# 完整迁移 Web 目录
rsync -avz --delete --progress \
  /var/www/ root@new-server:/var/www/

# 迁移数据库备份文件
rsync -avz /data/backups/ root@new-server:/data/backups/

SSH 免密配置

远程同步时频繁输入密码很烦人,配置 SSH 密钥可实现免密操作:

# 1. 生成 SSH 密钥
ssh-keygen -t ed25519 -C "your-email"

# 2. 复制公钥到远程服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote

# 3. 验证免密登录
ssh user@remote 'hostname'

软链接处理

# 保留软链接(默认)
rsync -a --links /src/ /dest/

# 将软链接转为实际文件内容复制
rsync -a --copy-links /src/ /dest/

# 保留软链接文件本身,但不递归跟随
rsync -a --keep-dirlinks /src/ /dest/

增量备份策略

使用 --link-dest 实现高效增量备份(基于硬链接):

# 第一次全量备份
rsync -avh /data/ /backups/backup_$(date +%Y%m%d)/

# 后续增量备份(未变化的文件通过硬链接指向上次备份)
rsync -avh --link-dest=/backups/backup_$(date -d yesterday +%Y%m%d) \
  /data/ /backups/backup_$(date +%Y%m%d)/

常见问题

问题 原因 解决
Permission denied SSH 或目录权限问题 检查 SSH 配置和目录权限
传输速度慢 未开启压缩 加上 -z 参数
中文文件名乱码 编码问题 确保两端系统编码一致(UTF-8)
同步后文件被错误删除 --delete 使用不当 先用 --dry-run 测试

总结

rsync 是 Linux 运维中不可或缺的工具。掌握 -avz(归档+详细+压缩)基础组合,配合 --delete(同步删除)和 --exclude(排除规则)可以应对绝大部分文件同步场景。对于备份场景,利用 --link-dest 实现的高效增量备份是一个值得掌握的高级技巧。

Comments | 2条评论