|
|
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_t="`date +%Y%m%d`"
inotify_d="/var/log/inotify"
#log files
inotify_events="$inotify_d/inotify_events.$inotify_t.log"
rsync_success="$inotify_d/rsync_success.$inotify_t.log"
rsync_error="$inotify_d/rsync_error.$inotify_t.log"
mkdir -p $inotify_d
/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_events |
/bin/awk -v rsync_success="$rsync_success" -v rsync_error="$rsync_error" '
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 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
}'
|
|