1、单纯使用rsync加入计划任务只能设置最少1分钟的间隔,而使用inotify事件触发小文件为秒级同步,取决于网速,和写入磁盘的速度
2、此脚本只对移动到监控的目录、监控目录中的目录有重命名的情况进行递归同步
3、其它需要进行同步的操作:
rsync+inotifywait实现数据实时同步(上篇:分析inotifywait产生的事件)
4、inotify-tools的安装:
安装inotify工具inotify-tools(inotifywait和inotifywatch)
注:
使用本脚本要求需要同步的服务器上的路径相同!
因为考虑到误删除的问题,所以本脚本没有使用同步删除功能,以后如果需要再添加……
一定要当前进程执行!如果sh program执行有的事件无法捕捉到,导致同步失败。
运行方式:
假设此脚本放在/下:
在/etc/rc.local中添加开机自启动、后台运行(为了方便排错推荐重定向错误到文件,如果有内容的话也应该是system()函数中的rsync错误):
有日志功能:
. /rsync_inotify_log.sh 2>/var/log/rsync_inotify.error >&2 &
无日志功能:
. /rsync_inotify_nolog.sh >/var/log/rsync_inotify.log 2>/var/log/rsync_inotify.error &
以下两个脚本,区别在于有日志功能和无日志功能(都已测试,推荐使用有日志功能的)
有日志功能:rsync_inotify_log.sh
#!/bin/bash #exec like:". program &",and don't like:"/bin/bash program &",(some events cannot be processed(pipe?)) #you can add above command line into /etc/rc.local inotify_d="/var/log/inotify" if [ ! -d "$inotify_d" ];then mkdir $inotify_d fi /usr/local/bin/inotifywait -mrq -e close_write,close_nowrite,create,moved_to,attrib,delete \ --format '%w*%f*%Xe' /tmp/rs\ ync/rs | tee $inotify_d/inotify_events.`date +%Y%m%d`.log | /bin/awk -v inotify_d=$inotify_d ' BEGIN{ FS="*" r_host="192.168.2.120" } function bslash(line, dpath) { if (dpath==1) { gsub(/ /,"\\\\&",line) gsub(/^/,"\"",line) gsub(/$/,"\"",line) } else { gsub(/ /,"\\\\&",line) } return line } { inotify_t=strftime("%Y%m%d") rsync_success=inotify_d"/rsync_success."inotify_t".log" rsync_error=inotify_d"/rsync_error."inotify_t".log" #SFTP file renamed start if ($3 ~ /^CREATE$/) { sftp_renamed_f=bslash($2) sftp_renamed_f_path=bslash($1) sftp_renamed_f_path_dest=bslash($1,1) } else if ($3 ~ /^DELETE$/) { if (sftp_renamed_f != "") { if (system("/usr/bin/rsync -ulDtpog -e ssh "sftp_renamed_f_path \ sftp_renamed_f" "r_host":"sftp_renamed_f_path_dest)==0) { print strftime("%Y%m%d%H%M%S")" : FILE(sftp renamed) : " \ sftp_renamed_f_path sftp_renamed_f >>rsync_success close(rsync_success) } else { print strftime("%Y%m%d%H%M%S")" : FILE(sftp renamed) : " \ sftp_renamed_f_path sftp_renamed_f >>rsync_error close(rsync_error) } sftp_renamed_f="" sftp_renamed_f_path="" sftp_renamed_f_path_dest="" } } else { sftp_renamed_f="" sftp_renamed_f_path="" sftp_renamed_f_path_dest="" } #SFTP file renamed end #new file create start if ($3 ~ /^CLOSE_WRITEXCLOSE$/ && ($2 !~ /\...*sw[a-z]x?$/)) { if (system("/usr/bin/rsync -ulDtpog -e ssh "bslash($1)bslash($2)" "r_host":"bslash($1,1))==0) { print strftime("%Y%m%d%H%M%S")" : FILE(create or cp -af) : "$1$2 >>rsync_success close(rsync_success) } else { print strftime("%Y%m%d%H%M%S")" : FILE(create or cp -af) : "$1$2 >>rsync_error close(rsync_error) } } #new file create end #file renamed or moved start if ($3 ~ /^MOVED_TO$/) { if (system("/usr/bin/rsync -ulDtpog -e ssh "bslash($1)bslash($2)" "r_host":"bslash($1,1))==0) { print strftime("%Y%m%d%H%M%S")" : FILE(renamed or moved) : "$1$2 >>rsync_success close(rsync_success) } else { print strftime("%Y%m%d%H%M%S")" : FILE(renamed or moved) : "$1$2 >>rsync_error close(rsync_error) } } #file renamed or moved end #dir create or cp -r start if ($3 ~ /^CREATEXISDIR$/) { if (system("/usr/bin/rsync -ulDtpog -d -e ssh "bslash($1)bslash($2)" "r_host":"bslash($1,1))==0) { print strftime("%Y%m%d%H%M%S")" : DIR(create or cp -r) : "$1$2 >>rsync_success close(rsync_success) } else { print strftime("%Y%m%d%H%M%S")" : DIR(create or cp -r) : "$1$2 >>rsync_error close(rsync_error) } } #dir create or cp -r end #dir renamed or moved start if ($3 ~ /^MOVED_TOXISDIR$/) { if (system("/usr/bin/rsync -ulDtpog -r -e ssh "bslash($1)bslash($2)" "r_host":"bslash($1,1))==0) { print strftime("%Y%m%d%H%M%S")" : DIR(renamed or moved) : "$1$2 >>rsync_success close(rsync_success) } else { print strftime("%Y%m%d%H%M%S")" : DIR(renamed or moved) : "$1$2 >>rsync_error close(rsync_error) } } #dir renamed or moved end #dir attrib changed start if ($3 ~ /^ATTRIBXISDIR$/ && $2 != "") { if ($2 in last_ad_c) { if ((++last_ad_c[$2]) == 4) { for (dnr in a_d) { if (system("/usr/bin/rsync -ulDtpog -d -e ssh " \ a_d_path[dnr] a_d[dnr]" "r_host":"a_d_path_dest[dnr])==0) { print strftime("%Y%m%d%H%M%S")" : DIR(attrib changed) : " \ a_d_path[dnr] a_d[dnr] >>rsync_success close(rsync_success) } else { print strftime("%Y%m%d%H%M%S")" : DIR(attrib changed) : " \ a_d_path[dnr] a_d[dnr] >>rsync_error close(rsync_error) } } delete last_ad_c delete a_d delete a_d_path delete a_d_path_dest } } else { ++last_ad_c[$2] a_d[NR]=bslash($2) a_d_path[NR]=bslash($1) a_d_path_dest[NR]=bslash($1,1) } } else if ($3 ~ /^CLOSE_NOWRITEXCLOSEXISDIR$/ && $2 == "") { for (dnr in a_d) { if (system("/usr/bin/rsync -ulDtpog -d -e ssh "a_d_path[dnr] a_d[dnr] \ " "r_host":"a_d_path_dest[dnr])==0) { print strftime("%Y%m%d%H%M%S")" : DIR(attrib changed) : " \ a_d_path[dnr] a_d[dnr] >>rsync_success close(rsync_success) } else { print strftime("%Y%m%d%H%M%S")" : DIR(attrib changed) : " \ a_d_path[dnr] a_d[dnr] >>rsync_error close(rsync_error) } } delete last_ad_c delete a_d delete a_d_path delete a_d_path_dest } else ; #dir attrib changed end #file attrib changed start if ($3 ~ /^CREATE$/) cp_f[NR]=$2 if ($3 ~ /^ATTRIB$/) { if (--NR in cp_f) last_cp_f=$2 if ($2 != last_cp_f) { if (system("/usr/bin/rsync -ulDtpog -e ssh "bslash($1) bslash($2) \ " "r_host":"bslash($1,1))==0) { print strftime("%Y%m%d%H%M%S")" : FILE(attrib changed) : " \ a_d_path[dnr] a_d[dnr] >>rsync_success close(rsync_success) } else { print strftime("%Y%m%d%H%M%S")" : FILE(attrib changed) : " \ a_d_path[dnr] a_d[dnr] >>rsync_error close(rsync_error) } last_cp_f="" } } #file attrib changed end }'
无日志功能:rsync_inotify_nolog.sh
#!/bin/bash /usr/local/bin/inotifywait -mrq -e close_write,close_nowrite,create,moved_to,attrib,delete \ --format '%w*%f*%Xe' /tmp/rs\ ync/rs | /bin/awk ' BEGIN{ FS="*" r_host="192.168.2.120" } function bslash(line, dpath) { if (dpath==1) { gsub(/ /,"\\\\&",line) gsub(/^/,"\"",line) gsub(/$/,"\"",line) } else { gsub(/ /,"\\\\&",line) } return line } { #SFTP file renamed start if ($3 ~ /^CREATE$/) { sftp_renamed_f=bslash($2) sftp_renamed_f_path=bslash($1) sftp_renamed_f_path_dest=bslash($1,1) } else if ($3 ~ /^DELETE$/) { if (sftp_renamed_f != "") { if (system("/usr/bin/rsync -ulDtpog -e ssh "sftp_renamed_f_path \ sftp_renamed_f" "r_host":"sftp_renamed_f_path_dest)==0) print "FILE(sftp renamed): "sftp_renamed_f_path sftp_renamed_f sftp_renamed_f="" sftp_renamed_f_path="" sftp_renamed_f_path_dest="" } } else { sftp_renamed_f="" sftp_renamed_f_path="" sftp_renamed_f_path_dest="" } #SFTP file renamed end #new file create start if ($3 ~ /^CLOSE_WRITEXCLOSE$/ && ($2 !~ /\...*sw[a-z]x?$/)) { if (system("/usr/bin/rsync -ulDtpog -e ssh "bslash($1)bslash($2)" "r_host":"bslash($1,1))==0) print "FILE(create or cp -af): "$1$2 } #new file create end if ($3 ~ /^MOVED_TO$/) { if (system("/usr/bin/rsync -ulDtpog -e ssh "bslash($1)bslash($2)" "r_host":"bslash($1,1))==0) print "FILE(renamed or moved): "$1$2 } if ($3 ~ /^CREATEXISDIR$/) { if (system("/usr/bin/rsync -ulDtpog -d -e ssh "bslash($1)bslash($2)" "r_host":"bslash($1,1))==0) print "DIR(create or cp -r): "$1$2 } if ($3 ~ /^MOVED_TOXISDIR$/) { if (system("/usr/bin/rsync -ulDtpog -r -e ssh "bslash($1)bslash($2)" "r_host":"bslash($1,1))==0) print "DIR(renamed or moved): "$1$2 } #dir attrib changed start if ($3 ~ /^ATTRIBXISDIR$/ && $2 != "") { if ($2 in last_ad_c) { if ((++last_ad_c[$2]) == 4) { for (dnr in a_d) { if (system("/usr/bin/rsync -ulDtpog -d -e ssh " \ a_d_path[dnr] a_d[dnr]" "r_host":"a_d_path_dest[dnr])==0) print "DIR(attrib changed): "a_d_path[dnr] a_d[dnr] } delete last_ad_c delete a_d delete a_d_path delete a_d_path_dest } } else { ++last_ad_c[$2] a_d[NR]=bslash($2) a_d_path[NR]=bslash($1) a_d_path_dest[NR]=bslash($1,1) } } else if ($3 ~ /^CLOSE_NOWRITEXCLOSEXISDIR$/ && $2 == "") { for (dnr in a_d) { if (system("/usr/bin/rsync -ulDtpog -d -e ssh "a_d_path[dnr] a_d[dnr] \ " "r_host":"a_d_path_dest[dnr])==0) print "DIR(attrib changed): "a_d_path[dnr] a_d[dnr] } delete last_ad_c delete a_d delete a_d_path delete a_d_path_dest } else ; #dir attrib changed end #file attrib changed start if ($3 ~ /^CREATE$/) cp_f[NR]=$2 if ($3 ~ /^ATTRIB$/) { if (--NR in cp_f) last_cp_f=$2 if ($2 != last_cp_f) { if (system("/usr/bin/rsync -ulDtpog -e ssh "bslash($1) bslash($2) \ " "r_host":"bslash($1,1))==0) print "FILE(attrib changed): " $1$2 last_cp_f="" } } #file attrib changed end }'