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

文章来源原创   作者:临窗旋墨   发布时间:2025-11-11   阅读:30   标签:运维 分类:我的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

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

  • 手动安装:

    1. # 如果还没安装编译工具,先执行这句
    2. sudo yum install -y gcc make automake autoconf libtool
    3. wget https://github.com/inotify-tools/inotify-tools/archive/refs/tags/3.20.1.tar.gz -O inotify-tools-3.20.1.tar.gz
    4. tar -zxvf inotify-tools-3.20.1.tar.gz
    5. cd inotify-tools-3.20.1/
    6. autoreconf -ivf
    7. ./configure
    8. make
    9. sudo make install
    10. ----
    11. # inotifywait --help
    12. 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

  1. #!/bin/bash
  2. ##############################################################################
  3. # 文件名称: realtime_sync.sh
  4. # 功能描述: 实时监控源目录文件变化并同步至目标服务器(用于备份)
  5. # 运行环境: Linux (依赖 inotify-tools, rsync)
  6. ##############################################################################
  7. ####################### 基本配置 ##########################
  8. SRC="/xqd/folder_sync/" # 源目录(A服务器)
  9. DEST="username@ip:/xqd/folder_sync/" # 目标目录(B服务器)
  10. LOG_DIR="/xqd/mine-shell/folder_rync/logs" # 日志目录
  11. LOG_FILE="$LOG_DIR/folder_sync.log" # 日志文件
  12. EVENTS="modify,create,delete,move,attrib" # 监听事件类型
  13. DELAY=3 # 防抖延迟(秒)
  14. ####################### 初始化部分 ##########################
  15. # 确保日志目录存在
  16. mkdir -p "$LOG_DIR"
  17. touch "$LOG_FILE"
  18. chmod 644 "$LOG_FILE"
  19. log() {
  20. echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
  21. }
  22. log "------------------------------------------------------"
  23. log "脚本启动,开始初始化同步(仅传输差异内容)"
  24. # 首次全量同步
  25. if rsync -az --delete-after --partial --inplace "$SRC" "$DEST" >> "$LOG_FILE" 2>&1; then
  26. log "初始化同步完成"
  27. else
  28. log "初始化同步时出现错误"
  29. fi
  30. # 防抖标志位
  31. waiting=0
  32. ####################### 实时监控与同步逻辑 ##########################
  33. log "开始监听目录: $SRC"
  34. # 这里的核心:inotifywait 通过“管道”把事件不断输出到 while 循环
  35. # 管道让整个监控流不占用前台输出,也不会阻塞终端
  36. # -m 表示持续监听
  37. # -r 表示递归
  38. # -q 静默模式,不打印多余信息
  39. # --format 指定只输出触发文件路径
  40. inotifywait -mrq --format '%w%f' -e "$EVENTS" \
  41. --exclude '\.swp$|~$|^4913$|\.swx$' "$SRC" | while read -r triggered_file; do
  42. if [ $waiting -eq 0 ]; then
  43. waiting=1
  44. (
  45. sleep $DELAY
  46. log "检测到变化,触发同步:$triggered_file"
  47. if rsync -az --delete-after --partial --inplace "$SRC" "$DEST" >> "$LOG_FILE" 2>&1; then
  48. log "同步完成(触发源:$triggered_file)"
  49. else
  50. log "同步出错(触发源:$triggered_file)"
  51. fi
  52. waiting=0
  53. ) &
  54. fi
  55. 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

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

可以定时重启:

  1. 0 2 * * * /path/to/restart_sync.sh

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

1创建自定义配置文件

路径:/etc/logrotate.d/folder_sync

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

2 验证配置

  1. logrotate -d /etc/logrotate.d/folder_sync

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

3 手动测试切割

  1. logrotate -f /etc/logrotate.d/folder_sync

用 systemd 管理

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

  1. [Unit]
  2. Description=Folder realtime sync service
  3. After=network.target
  4. [Service]
  5. ExecStart=/xqd/mine-shell/folder_rync/realtime_sync.sh
  6. Restart=always # 意外退出时自动重启
  7. # User=root # 根据实际用户调整
  8. StandardOutput=null # 输出重定向到日志(或脚本内已处理)
  9. StandardError=journal
  10. [Install]
  11. WantedBy=multi-user.target

启用

  1. systemctl daemon-reload
  2. systemctl enable folder-sync.service
  3. systemctl start folder-sync.service
  4. systemctl status folder-sync.service

2025-11-11整理 by Vic.xu


发表评论

目录