基于rsync、inotify-tools的文件同步

原创 临窗旋墨 2025-11-11 阅读:1129 分类: Linux运维 专题: Linux小主机实践 标签: 运维

基于rsync、inotify-tools的文件同步

一 总体流程

  1. 准备工作:确认两台服务器网络互通,确定需要同步的源目录和目标目录,检查并安装 rsync、inotify-tools 工具。
  2. 配置免密登录:在源服务器生成 SSH 密钥对,将公钥复制到目标服务器,实现免密登录(避免同步时输入密码)。
  3. 测试 Rsync 基础同步:手动执行一次 rsync 命令,验证源目录到目标目录的基础同步功能是否正常。
  4. 编写监控脚本:创建脚本,利用 inotify 监控源目录的变化,当有文件新增 / 修改 / 删除时,自动触发 rsync 进行同步。
  5. 设置自动运行:将脚本配置为系统服务或添加到开机启动,确保监控和同步能持续运行。

二 准备工作

软件安装:

  • aptsudo apt update && sudo apt install -y rsync inotify-tools
  • yumsudo yum install -y rsync inotify-tools

检查安装结果:

  • 检查 rsyncrsync --version(能显示版本信息即为成功)
  • 检查 inotify-toolsinotifywait --version(能显示版本信息即为成功)
遇到的问题:

1. Unable to find a match: inotify-tools

  • 换源安装:失败, 有冲突

  • 手动安装:

    复制代码
    # 如果还没安装编译工具,先执行这句
    sudo yum install -y gcc make automake autoconf libtool
    wget https://github.com/inotify-tools/inotify-tools/archive/refs/tags/3.20.1.tar.gz -O inotify-tools-3.20.1.tar.gz 
    tar -zxvf inotify-tools-3.20.1.tar.gz
    cd inotify-tools-3.20.1/
    autoreconf -ivf
    ./configure
    make
    sudo make install
    ----
    # inotifywait --help
    inotifywait 3.20.1

三 配置免密登录

  1. 生成秘钥对: ssh-keygen -t rsa -P ""
  2. 将源服务器的公钥复制到目标服务器:ssh-copy-id 目标服务器用户名@目标服务器IP
  3. 如果2不好操作,可以手动处理:
    1. 复制公钥,到目标服务器
    2. 手动追加:cat id_rsa.pub >> ~/.ssh/authorized_keys
  4. 测试免密登录: ssh 目标服务器用户名@目标服务器IPexit退出

四 文件同步脚本

/xqd/mine-shell/folder_rync/realtime_sync.sh

复制代码
#!/bin/bash
##############################################################################
# 文件名称: realtime_sync.sh
# 功能描述: 实时监控源目录文件变化并同步至目标服务器(用于备份)
# 运行环境: Linux (依赖 inotify-tools, rsync)
##############################################################################

####################### 基本配置 ##########################
SRC="/xqd/folder_sync/"                                       # 源目录(A服务器)
DEST="username@ip:/xqd/folder_sync/"                          # 目标目录(B服务器)
LOG_DIR="/xqd/mine-shell/folder_rync/logs"                    # 日志目录
LOG_FILE="$LOG_DIR/folder_sync.log"                           # 日志文件
EVENTS="modify,create,delete,move,attrib"                     # 监听事件类型
DELAY=3                                                       # 防抖延迟(秒)

####################### 初始化部分 ##########################
# 确保日志目录存在
mkdir -p "$LOG_DIR"
touch "$LOG_FILE"
chmod 644 "$LOG_FILE"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
}

log "------------------------------------------------------"
log "脚本启动,开始初始化同步(仅传输差异内容)"

# 首次全量同步
if rsync -az --delete-after --partial --inplace "$SRC" "$DEST" >> "$LOG_FILE" 2>&1; then
    log "初始化同步完成"
else
    log "初始化同步时出现错误"
fi

# 防抖标志位
waiting=0

####################### 实时监控与同步逻辑 ##########################
log "开始监听目录: $SRC"

# 这里的核心:inotifywait 通过“管道”把事件不断输出到 while 循环
# 管道让整个监控流不占用前台输出,也不会阻塞终端
# -m 表示持续监听
# -r 表示递归
# -q 静默模式,不打印多余信息
# --format 指定只输出触发文件路径
inotifywait -mrq --format '%w%f' -e "$EVENTS" \
    --exclude '\.swp$|~$|^4913$|\.swx$' "$SRC" | while read -r triggered_file; do

    if [ $waiting -eq 0 ]; then
        waiting=1
        (
            sleep $DELAY
            log "检测到变化,触发同步:$triggered_file"
            if rsync -az --delete-after --partial --inplace "$SRC" "$DEST" >> "$LOG_FILE" 2>&1; then
                log "同步完成(触发源:$triggered_file)"
            else
                log "同步出错(触发源:$triggered_file)"
            fi
            waiting=0
        ) &
    fi
done

基于脚本的一些命令:

  • 执行权限chmod +x /xqd/mine-shell/folder_rync/realtime_sync.sh
  • 后台启动: nohup ./realtime_sync.sh >/dev/null 2>&1 &
  • 关闭进程: pkill -f realtime_sync.sh
  • 查看进程:ps -ef | grep realtime_sync.sh | grep -v grep : 两个进程 一个父一个while子
  • 查看日志tail -f /xqd/mine-shell/folder_rync/logs/folder_sync.log\
  • 搜索包含"错误"的日志:

重启动脚本:restart_sync.sh

复制代码
#!/bin/bash
# 终止正在运行的脚本进程
pkill -f "realtime_sync.sh"
# 等待几秒确保进程退出
sleep 3
# 启动新的脚本实例(后台运行,输出重定向)
nohup /xqd/mine-shell/folder_rync/realtime_sync.sh >/dev/null 2>&1 &

可以定时重启:

复制代码
0 2 * * * /path/to/restart_sync.sh

五 使用系统自带 logrotate 进行日志切割

1创建自定义配置文件

路径:/etc/logrotate.d/folder_sync

复制代码
/xqd/mine-shell/folder_rync/logs/folder_sync.log {
    # 每天轮转一次
    daily
    # 保留7个历史日志
    rotate 7
    # 压缩旧日志
    compress
    # 延迟一天再压缩
    delaycompress
    # 忽略文件不存在
    missingok
    # 空文件不轮转
    notifempty
    # 新文件权限设置为644,属主和属组为root
    create 644 root root
    sharedscripts
    postrotate
        # 日志切割后重载服务(可选)
        systemctl reload folder-sync.service >/dev/null 2>&1 || true
    endscript
}

2 验证配置

复制代码
logrotate -d /etc/logrotate.d/folder_sync

-d 是 debug 模式,不实际切割,只显示将执行的操作。

3 手动测试切割

复制代码
logrotate -f /etc/logrotate.d/folder_sync

用 systemd 管理

/etc/systemd/system/folder-sync.service

shell 复制代码
[Unit]
Description=Folder realtime sync service
After=network.target

[Service]
ExecStart=/xqd/mine-shell/folder_rync/realtime_sync.sh
Restart=always  # 意外退出时自动重启
# User=root       # 根据实际用户调整
StandardOutput=null  # 输出重定向到日志(或脚本内已处理)
StandardError=journal

[Install]
WantedBy=multi-user.target

启用

复制代码
systemctl daemon-reload
systemctl enable folder-sync.service
systemctl start folder-sync.service
systemctl status folder-sync.service

2025-11-11整理 by Vic.xu

评论区

avatar
未登录

暂无评论,来发表第一条评论吧~