当 rsyncdaemon 接收到某个文件夹的文件更改后,如何触发脚本运行?

当 rsyncdaemon 接收到某个文件夹的文件更改后,如何触发脚本运行?

我有几台运行 rsyncd 的服务器。我不使用 ssh 隧道,而是使用本机 rsync 协议。同步文件的一个文件夹包含应形成 iso 映像的文件。每当上传该文件夹中的文件(从远程推送到此服务器)时,它都会自动重新创建 iso 文件。理想情况下,只有文件内容或大小更改才会触发此操作,因为我想在网页内显示 iso 的最后更改日期,用户可以下载并刻录它。

因为 iso 很大,所以只要有一个文件发生变化,我就想在每台服务器上创建它。我不想同步 iso 本身

答案1

这更像是对 Gilles 的回应,但我想格式化一些代码;监控已更改文件的一个巧妙方法是存储目录的 md5sum 的 md5sum,ala:

find /path/to/iso/data/ -type f -exec md5sum {} + | awk '{print $1}' | sort | md5sum | awk '{print $1}'

...它将为您提供以下类型的输出:

b843afc89097f0abc062e0d0e14d480b

如果您在 cron 的每次迭代中保存它,那么这是一种非常快速有效的方法,可以确定目标上的内容是否已更改。您甚至可以围绕 xinetd rsync 守护进程构建一个包装器;将对 /etc/xinetd.d/rsync 中的二进制文件的调用替换为:

server          = /usr/bin/rsync

...使用脚本:

server          = /path/to/script.sh

然后在脚本中比较并在守护进程每次以有效 0 状态退出时执行操作。这比 cron 作业自动化得多,好处是只有当您将其编码为 rsync exit 0 时它才会运行。类似于...(此处为伪代码):

#!/bin/sh

/usr/bin/rsync "$*"

if [ $? -eq 0 ]; then
  OLDVALUE=`cat /var/cache/isodata.txt`
  NEWVALUE=`find /path/to/iso/data/ -type f -exec md5sum {} + | awk '{print $1}' | sort | md5sum | awk '{print $1}'`
  if [ ${OLDVALUE} != ${NEWVALUE} ]; then
    -- run ISO making code --
    echo ${NEWVALUE} > /var/cache/isodata.txt
  fi
fi

这是开始的总体想法。

答案2

老式、便携、笨拙的方法是定期运行 iso 生成脚本,可以通过 cron 或循环运行while sleep(最好在间隔不明显大于重新生成 iso 所需的时间的情况下运行)。为避免在文件未更改的情况下重新生成 iso,请仅在 时执行[ -n "$(find -cnewer foo.iso -print -quit)" ]此操作。请注意,如果删除了某些文件且未更改或添加任何文件,则不会触发此操作。

一种更好但不可移植的方法是使用平台的文件更改监视 API:IRIX 和其他一些系统上的 fam、*BSD 上的 kqueue、Linux 上的 inotify 等。所有这些都可以轻松设置为在文件(包括目录)更改时运行命令;我不知道它们是否都可以监视目录树。

另一种方式是将文件放在用户空间文件系统(例如 FUSE)上,该系统只将调用传递给底层存储,但修改会触发 iso 的重新生成。

无论你最终做什么,请注意,在重新生成 iso 时文件可能会发生变化;在这种情况下,你有两种策略。你可以等到生成完成后再重新开始,但这样做很浪费。或者你可以终止 iso 生成并重新开始,但如果文件的修改速度比 iso 生成速度快,这可能会导致很长时间没有 iso 更新。将两者结合起来,即在超过 X 时间内没有生成 iso 时终止 iso 生成,这是一个合理的解决方案。

相关内容