ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 使用Inotify+rsync同步数据 Inotify 一种强大的、细粒度的、异步文件系统监控机制,它满足各种各样的文件监控需要,可以监控文件系统的访问属性、读写属性、权限属性、删除创建、移动等操作,也就是可以监控文件发生的一切变化。 inotify-tools 是一个C库和一组命令行的工作,提供Linux下inotify的简单接口。inotify-tools安装后会得到inotifywait和inotifywatch这两条命令: * inotifywait命令可以用来收集有关文件访问信息,Linux发行版一般没有包括这个命令,需要安装inotify-tools,这个命令还需要将inotify支持编译入Linux内核,好在大多数Linux发行版都在内核中启用了inotify。 * inotifywatch命令用于收集关于被监视的文件系统的统计数据,包括每个 inotify 事件发生多少次。 ### 在CentOS下安装inotifywait ~~~ #yum search inotify-tools #yum info inotify-tools sudo yum install inotify-tools ~~~ > MacOS下可以使用fswatch替代。fswatch是苹果内置软件,也可以在其他平台上安装。 ### 配置脚本 ~~~ #!/usr/bin/env bash # 记录进程号,可使用 ps -ef |grep notify.sh 查看 LOCK_NAME="/var/run/notify.pid" # 本地待同步的目录 SOURCE="/www/vhost" # 目标服务器及目录 TARGET="root@<ip_address>:/www/" # 排除的目录 EXCLUDE="cache" # 远程登录命令 SSH="ssh -p 22" # 日志 LOG="/var/log/notify_update_" # 设置禁止重定向覆盖 set -o noclobber ,即不能使用 > ,但可以使用 >> # 设置恢复重定向覆盖 set +o noclobber ,即职能使用 >> 和 >| # 2> 标准错误(stderr) # 1> 标准输出(stdout) # &> 同时输出到 stdout 和 stderr # /dev/null 位桶(bit bucket)或黑洞 # true: 0,false: 1。 # $? 退出码 if (set -o noclobber; echo "$$" > "$LOCK_NAME") 2> /dev/null; then # trap command signal # INT 中断进程 CTRL+C # TERM 软件终止信号 # 全部信号列表:trap -l # 非正常退出时,自动删除进程文件 trap 'rm -f "$LOCK_NAME"; exit $?' INT TERM EXIT # yum install inotifywait # -m | --monitor 持续监听 # -r | --recursive 递归子目录 # -e | --event <eventl> 指定要监听的事件,多个事件用逗号隔开 # 文件有变动的事件:create/delete/move/attrib/close_write inotifywait -mr \ # 指定输出的时间格式,赋给 %T --timefmt '%Y-%m-%d %H:%M' \ # 设置打印格式%T时间;%w触发事件文件所在绝对路径;%f触发事件文件名称;%e触发的事件名称; --format '%T %w%f %e' \ -e create,move,close_write,delete,attrib $SOURCE \ --exclude $EXCLUDE | while read date time file event; do # 当前日期,用于日志文件名 today=`date +%Y-%m-%d` # 遍历事件 case $event in # 立即更新 MOVED_TO,ISDIR|MOVED_TO | CLOSE_WRITE,CLOSE) # 如果同步未完成,忽略本次同步 ps aux | grep [r]sync if [ $? -ne 0 ]; then # 同步前计时器 t1=`date +%s` # 文件同步 rsync -a --delete --numeric-ids -e $SSH $SOURCE $TARGET & # 同步后计时器 t2=`date +%s` # 计算文件更新完成的时间差 dt=$(($t2 - $t1)) # 写日志 echo "[${date} ${time}] UPDATE ${file} ${dt}" >> $LOG_${today}.txt fi ;; # 目录和文件的删除,可暂不更新 DELETE,ISDIR | DELETE) echo "[${date} ${time}] UPDATE ${file} ${dt}" >> $LOG_${today}.txt ;; # 创建目录,修改文件和目录的属性,可暂不更新 CREATE,ISDIR | ATTRIB,ISDIR | ATTRIB) ;; esac done # 清除进程文件 rm -f $LOCK_NAME #取消信号锁定 trap - INT TERM EXIT else # 写进程文件失败意味着程序在运行中,或者为正常关闭 echo "The application is running, lock file name is $LOCK_NAME." exit 1 fi ~~~ 由于 fswatch 具有跨平台的优势,下面给出一个同步化示例。 ~~~ #!/usr/bin/env bash ## 保持源目录 LOCAL_DIR 和 目标目录 REMOTE_DIR 同步 ## 源目录 LOCAL_DIR=/usr/local/var/www/project ## 目标目录 REMOTE_DIR=/home/www/project # pull #rsync -avz --numeric-ids --exclude-from 'rsync_pull.txt' -e 'ssh -p 2222' pat@1.2.3.4:/home/www/ /usr/local/var/www/ # push fswatch -e "runtime" -e "temp" -d $LOCAL_DIR | while read LOCAL_FILE do ## 构造目标文件(包括文件夹) REMOTE_FILE="${REMOTE_DIR}/${LOCAL_FILE##$LOCAL_DIR/}" SOURCE=$(dirname $LOCAL_FILE)/ TARGET=$(dirname $REMOTE_FILE)/ echo $SOURCE >> ./rsync.log 2>&1 #echo $TARGET rsync \ -P \ -S \ --delete --delete-after \ --exclude-from 'rsync_push.txt' \ -avz -e 'ssh -p 2222' \ $SOURCE \ pat@1.2.3.4:$TARGET done ~~~