分享三个不同目录双向更新的实用方法

2023-11-08

方法一.rsync +判断脚本,进行双向更新

脚本内容如下:

#!/bin/bash
# 本地目录路径
local_dir="/path/to/local/dir"
# 远程目录路径
remote_dir="/path/to/remote/dir"
# 获取本地目录中最近修改的文件的修改时间
local_mtime=$(find "$local_dir" -type f -printf '%T@\n' | sort -n | tail -1  | awk '{print int($1)}' )
# 获取远程目录中最近修改的文件的修改时间
remote_mtime=$(ssh user@remote_host "find "$remote_dir" -type f -printf '%T@\n' | sort -n | tail -1  | awk '{print int(\$1)}' ")
# 比较两个目录中最近修改的文件的修改时间,时间越新的一方向旧的一方同步数据
if [ "$local_mtime" -gt "$remote_mtime" ]; then
   rsync -az /path/to/local/dir/ user@remote_host:/path/to/remote/dir/
else [ "$local_mtime" -lt "$remote_mtime" ]; then
    rsync -az    user@remote_host:/path/to/remote/dir/     /path/to/local/dir/ 
fi

这样,脚本加上定时任务就可以进行双向同步更新了,在这个脚本里我踩了很多坑,

  • 比如find 的 -printf ‘%T@\n’ 选项,%T@ 表示以秒为单位的时间戳,\n 表示换行符,这样打印出来的时间戳是有小数的,在最后的if判断中用到-gt比较,这里只能用整数进行比较,用小数比较会报错所以要用最后的awk ’{print int{$1}'来取整,
  • 再一个是要主要ssh 到远端执行命令的时候一定要加 双引号"",将执行的命令放在双引号中,还有就是特殊符号要转义,如$符号,不然会报错执行不了, 如上面获取远端的mtime命令
remote_mtime=$(ssh user@remote_host "find "$remote_dir" -type f -printf '%T@\n' | sort -n | tail -1  | awk '{print int(\$1)}' ") 

注:这个脚本只适合主备同步,如果两个目录同时开写,则不适合

方法二.使用rsync的-u选项

在写上一个脚本之前我并不知道rsync的-u选项,后来发现这个选项更加简单方便,-u 或 --update 选项的作用是表示“仅更新”。这意味着 rsync 会跳过那些目标目录中已经存在且比源目录中的文件新的文件。换句话说,它只会更新目标目录中的文件比源目录中的文件旧的文件。
例如,如果您想要从源目录同步文件到目标目录,但是只想更新那些目标目录中比源目录中的文件旧的文件,您可以使用以下命令:

rsync -avu /path/to/source/ /path/to/destination/

有了这个选项,上面方法一中的脚本就会简单很多了,就可以优化成下面的样子

#!/bin/bash
rsync -avzuX    /path/to/local/dir/     user@remote_host:/path/to/remote/dir/
rsync -avzuX    user@remote_host:/path/to/remote/dir/     /path/to/local/dir/

然后再加上定时任务就可以了,这样也不用担心互相覆盖的问题
扩展rsync的一个选项 -X

一般使用rsync,常用的选项是 -avzuX
其中-a选项是归档模式,包含很多选项,相当于-rlptgoD,其中各个选项的含义如下:
-r:递归复制目录及其内容。
-l:复制符号链接。
-p:保留文件权限。
-t:保留文件修改时间。
-g:保留文件所属组。
-o:保留文件所有者。
-D:传输特殊和块设备。

-v选项表示详细输出,用于显示更多关于传输过程的信息。
-z选项表示在传输过程中压缩数据
-u选项在上面介绍过了已经
-X 选项 :-X选项是保留扩展属性,扩展属性属于文件系统中的元数据,是一种文件系统功能,它允许用户将元数据与文件和目录关联。这些元数据存储在文件系统中,但不属于文件的正文内容。扩展属性通常用于存储与特定应用程序相关的信息,例如文件的MIME类型或字符集编码。
查看一个文件的扩展属性可以用getafttr命令查看,设置一个文件的扩展属性可以用setfattr命令设置,如下,设置一个文件的作者,
其中-n选项用于指定新属性的名称(名称可以自定义,但是会受不同文件系统的一些限制,例如长度),-v选项用于给新属性赋值,-x:删除指定的扩展属性。
iguagua

方法三,使用rsync+inotify监控工具

脚本如下

#!/bin/bash
#本地目录路径
local_dir="/path/to/local/dir"
#远程目录路径
remote_dir="/path/to/remote/dir"
#监控本地目录中的更改
inotifywait -mrq --format '%w%f' -e close_write,delete,create,attrib $local_dir | while read file
do
# 使用 rsync 命令将更改实时同步到远程目录
rsync -avz --delete  $local_dir   user@remote_host:$remote_dir
done

#使用 nohup 命令来确保脚本在您退出 shell 会话后继续运行,且将脚本的标准输出和标准错误重定向到 sync.log 文件中,因此您可以通过查看该文件来查看脚本的输出。

nohup ./sync.sh > sync.log 2>&1 &

注释:
inotify工具linux系统不自带,在系统自带的安装包里没有,需要另外下载
下载安装
方法:
wget --no-check-certificate https://jaist.dl.sou.com/inotify/inotify-tools-3.14.tar.gz
tar -zxvf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure
make
make install

inotifywait -mrq --format '%w%f' -e close_write,delete,create,attrib $local_dir | while read file

关于上面这条inotify命令的解释

这条命令使用inotifywait监视$local_dir目录及其子目录中的文件更改。

--format '%w%f'选项指定了输出格式,

其中%w表示事件发生的文件所在的目录,%f表示事件发生的文件名。

管道符号(|)将inotifywait命令的输出传递给后面的命令。

while read file循>环读取每一行输出,并将其存储在变量file中。这样,您就可以在循环内
部访问每个更改的文件

-mrq 和 -e 都是 inotifywait 命令的选项。

-m(或 --monitor)选项用于使 inotifywait 命令持续运行,而不是在第一个事件发生后退出。这样,它就可以持续监控文件系统事件。

-r(或 --recursive)选项用于递归地监控目录及其子目录中的所有文件和子目录。

-q(或 --quiet)选项用于禁止 inotifywait 命令输出统计信息和错误信息。

-e(或 --event)选项用于指定要监控的事件类型。在上面的示例脚本中,它被配置为监控 close_write、delete、create 和 attrib 事件。这意味着当文件被写入并关闭、删除、创建或属性更改时,inotifywait 命令会输出相应的文件路径。
因此,-mrq -e close_write,delete,create,attrib 选项会使 inotifywait 命令持续运行并递归地监控目录及其子目录中的所有文件和子目录,禁止输出统计信息和错误信息,并在发生指定类型的事件时输出相应的文件路径。

扩展

  • Unison 同步工具
    在 Linux 系统中,有一些工具可以实现两个不同目录之间的双向同步。其中一个常用的工具是 rsync 命令。rsync 可以在单向同步,因此需要运行两次来实现双向同步。
    另一个可以实现双向同步的工具是 Unison 文件同步器。Unison 可以用来在两个本地目录或两个远程目录之间同步文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

分享三个不同目录双向更新的实用方法 的相关文章

随机推荐