阿飞
阿飞
发布于 2025-07-28 / 1 阅读
0
0

rsync同步文件命令介绍

rsync 是 Linux/Unix 系统中非常常用的文件同步工具,它可以高效地在本地或远程主机之间同步文件和目录。以下是对 rsync 命令的 由浅入深 的介绍,包括语法、常用参数、实战案例及高级用法。

一、基础概念

1. rsync 的作用

  • 同步本地文件/目录;

  • 同步远程文件/目录(通过 SSH);

  • 支持增量复制(只同步变化的部分);

  • 支持压缩传输、权限保留、断点续传等功能。

2. 基本语法

rsync [选项] 源路径 目标路径

源路径和目标路径都可以是本地路径,也可以是远程路径(格式为 user@host:/path)。

二、常用参数说明(基础)

参数

含义

-a

归档模式,相当于 -rlptgoD,保留权限等信息

-v

显示同步过程中的详细信息(verbose)

-z

在传输过程中进行压缩(适合网络慢的场景)

-r

递归复制子目录(-a 中已包含)

-P

显示进度,并保留已传输的数据(可断点续传)

--delete

删除目标目录中源目录没有的文件

-e ssh

指定使用 SSH 作为远程 shell

三、简单示例(从易到难)

1. 本地同步文件夹

rsync -av /home/user/docs/ /backup/docs/
  • /home/user/docs/ 同步到 /backup/docs/

  • -a 保留权限,-v 显示过程

  • 注意源路径最后的 / 表示目录内容,不加则会把整个目录拷贝进去


2. 同步到远程服务器

rsync -avz /home/user/docs/ user@remote:/data/docs/
  • 将本地 /home/user/docs/ 同步到远程服务器 /data/docs/

  • 使用 SSH 传输,自动压缩,提高效率


3. 从远程服务器拉取文件

rsync -avz user@remote:/data/docs/ /home/user/docs/
  • 从远程服务器 /data/docs/ 拉取文件到本地


4. 使用 --delete 保持完全一致

rsync -avz --delete /home/user/docs/ user@remote:/data/docs/
  • 如果远程目录比源目录多出文件,会被删除

  • 谨慎使用,可能导致数据丢失


四、高级用法

1. 指定排除文件或目录

rsync -av --exclude "node_modules/" --exclude "*.log" /src/ /dest/
  • 不同步 node_modules 文件夹和 .log 文件

2. 使用 SSH 指定端口

rsync -av -e "ssh -p 2222" /src/ user@host:/dest/
  • 如果 SSH 不是默认 22 端口,可以这样指定

3. 使用 rsync 同步定时任务(crontab)

编辑定时任务:

crontab -e

添加如下任务,每天凌晨 2 点同步一次:

0 2 * * * rsync -az /data/backup/ user@remote:/data/sync/

五、实用技巧

需求

命令

显示同步差异(不执行)

rsync -avnc src/ dest/

限速传输

rsync --bwlimit=5000 -avz src/ dest/ (单位 KB/s)

使用密码认证

建议配合 SSH 密钥使用,无需输入密码

只同步文件结构

rsync -av --include '*/' --exclude '*' src/ dest/

六、总结

场景

推荐命令

本地同步

rsync -av /src/ /dest/

同步到远程

rsync -avz /src/ user@host:/dest/

保持完全一致

rsync -avz --delete /src/ user@host:/dest/

忽略部分文件

rsync -av --exclude "xxx" /src/ /dest/

自动化定时同步

配合 crontab 实现自动化

七、实用脚本

1. 同步本服务器指定目录下最近7天修改的文件到目标服务器

#!/bin/bash

# 定义源目录和目标目录
SOURCE_DIR="/home/ubuntu/tmp/rsync-test/"
DEST_DIR="/root/tmp/rsync-test/"

# 定义目标服务器的用户名和IP地址
# 请替换为您实际的目标服务器信息
TARGET_USER="root"
TARGET_HOST="your_target_server_ip" # 例如:192.168.1.100

# 要同步的时间范围(天)
DAYS=7

# 定义日志文件路径
LOG_FILE="/var/log/rsync_recent_files.log"

# --- 函数定义 ---

# 记录日志
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# --- 脚本开始 ---

log_message "同步任务开始..."

# 确保源目录存在
if [ ! -d "$SOURCE_DIR" ]; then
    log_message "错误:源目录 '$SOURCE_DIR' 不存在。"
    exit 1
fi

# 查找最近7天创建的文件,并将它们的相对路径输出到临时文件
# -maxdepth 1 限制只查找当前目录下的文件,不深入子目录
# 如果需要包含子目录中的文件,请删除 -maxdepth 1
# -type f 确保只查找文件,不包括目录
# -ctime -7 查找在7天内创建的文件 (change time, 对于新创建的文件通常等于creation time)
# -printf "%P\n" 输出相对于SOURCE_DIR的路径名
log_message "正在查找 '$SOURCE_DIR' 中最近7天创建的文件..."
#find "$SOURCE_DIR" -maxdepth 1 -type f -ctime -7 -printf "%P\n" > /tmp/rsync_files_list.tmp
find "$SOURCE_DIR" -type f -ctime -$DAYS -printf "%P\n" > /tmp/rsync_files_list.tmp

# 检查是否有找到文件
if [ ! -s /tmp/rsync_files_list.tmp ]; then
    log_message "在 '$SOURCE_DIR' 中没有找到最近7天创建的文件,跳过同步。"
    rm -f /tmp/rsync_files_list.tmp
    log_message "同步任务完成,没有文件需要同步。"
    exit 0
fi

log_message "找到以下文件需要同步(详情请查看 /tmp/rsync_files_list.tmp):"
# cat /tmp/rsync_files_list.tmp >> "$LOG_FILE" # 如果你想在日志中也包含文件列表,可以取消注释这行

# 使用 rsync 同步文件
# -a: 归档模式,等同于 -rlptgoD (递归、保留符号链接、权限、时间戳、组、所有者、设备文件)
# -v: 详细输出
# -z: 压缩文件数据传输
# --files-from: 从文件中读取要同步的文件列表
# --include-from=/tmp/rsync_files_list.tmp: 仅包含列表中的文件
# --exclude='*': 排除所有其他文件,确保只同步列表中指定的文件
# --remove-source-files: (可选) 如果需要同步后删除源文件,请取消注释此行
log_message "正在将文件同步到 ${TARGET_USER}@${TARGET_HOST}:${DEST_DIR}..."
rsync -azv --files-from=/tmp/rsync_files_list.tmp "$SOURCE_DIR" "${TARGET_USER}@${TARGET_HOST}:${DEST_DIR}"

# 检查 rsync 命令的退出状态
RSYNC_STATUS=$?
if [ $RSYNC_STATUS -eq 0 ]; then
    log_message "文件同步成功完成。"
elif [ $RSYNC_STATUS -eq 24 ]; then
    log_message "文件同步完成,但有一些文件在传输过程中消失了(这不是一个错误)。"
else
    log_message "错误:文件同步失败,rsync 退出状态码:$RSYNC_STATUS"
fi

# 清理临时文件
rm -f /tmp/rsync_files_list.tmp
log_message "临时文件已清理。"

log_message "同步任务结束。"

exit 0


评论