【问题标题】:Automatically actioning remote copy of folder when local copy changes本地副本更改时自动操作文件夹的远程副本
【发布时间】:2019-02-03 18:06:45
【问题描述】:

编辑:我看到有人投票结束这个问题,因为“问题太宽泛”,但我上次发帖询问如何做某事时,我 被要求提供更多关于我想做什么和为什么要做的细节。 所以……赢不了!我只问一个问题:“当本地副本更改时如何操作文件夹的远程副本”。我不是在问如何重命名、重新编号或制作 zip 文件,只是解释这是我作为副本的一部分需要做的事情。我实在想不出更详细的提问方式 这没有明显(但错误)的答案是“只使用 rsync”。

我想在 Ubuntu 18.04 上根据 Dropbox 文件夹(其他服务也可以添加文件)中完成的上传活动自动复制文件夹。我需要:

  • 保持源文件夹不变。
  • 如果还没有复制的文件名,则为复制的文件名添加数字前缀 - (find . -name '[[:digit:]]*.mp3' 等)
  • 清除撇号的文件名(例如,使用“detox”)。
  • 在远程端创建文件夹的 zip。
  • 如果将来源文件夹发生任何变化,请在远程副本上重新复制并重新创建 zip 文件夹。

示例:20190203 的 SOURCE 文件夹

   apostrophe's.mp3
   track01.mp3
   zebra 4.mp3

20190203的REMOTE文件夹(处理后)

   01-apostrophes.mp3
   02-track01.mp3
   03-zebra4.mp3
   20190302.zip

如果远程用户在一个月后在源文件夹中添加 chickens.mp3 并删除 apostrophe's.mp3,该过程将通过重新更新远程文件夹复制和重命名文件夹,并自动重建 zip 文件。

所有可能上传的单个文件都小于 10Mb,因此即使是最慢的连接,上传任何一个文件的时间也不会超过 15 分钟,但上传整个文件夹可能需要 45 分钟。

我无法根据文件夹大小、文件数量或修改日期检查更改,因为将 zip 文件添加到远程文件夹的操作会更改所有这些。

目前,我有一个每小时 crontab 运行一个包含以下内容的脚本:

SCANDIRS="$(find $BASEDIR -type f -mmin +15 -mmin -45 -printf "%h\\n" | sort -u | xargs -n 1 realpath)"

然后它循环遍历scandirs并发挥作用,但这可能有很多我没有预见到的问题,每小时只能运行一次,并且不允许更新旧文件夹。

我知道rsync -av --delete 如果它是 just 文件,则使用常规 crontab 会起作用,但我完全不知道如何做我想做的事。复制的文件夹将驻留在同一个本地文件系统上(如果您想知道,请远程获取s3 synced!)。

我认为inotifywait 可能是一个解决方案,但我不确定如何处理“等到文件夹静止一段时间但允许以后随时更新”的问题。

谢谢。

【问题讨论】:

  • 如果您有空间在本地保存文件夹的临时副本,您可以执行本地 rsync,然后仅在有任何更改时重新创建您的 zip。否则,您可以维护一个 md5 校验和文件并以相同的方式使用它。或者甚至可能只是find -newer timestamp
  • 我可能没有清楚地解释上述问题,但由于我已经概述的原因,上述任何一项都不可能,特别是关于更改时间戳/添加的副本中的项目文件夹。
  • 所以你没有办法查询SOURCE的状态?我不是在谈论查询 REMOTE 的状态。您的问题中的find -mmin 不是在查询 SOURCE 吗?
  • 类似的东西。我在想更多do_sync; touch timestamp; / if find source -newer timestamp | grep -qc .; then do_sync_changes; fi。然后你还要在源代码中删除(因为目录时间本身应该改变)。
  • -type d 将阻止 find 明确查找更改的文件(touch dir/file 不会更改 dir)。使用-cnewer timestamp 可能会更好。 grep 停止将 find 的结果喷到标准输出上。

标签: bash ubuntu rsync inotifywait


【解决方案1】:

总结一下我的 cmets,检查更改的简单 bash 脚本框架可能类似于:

SOURCE=/my/folder/to/check
WORK=/my/state/folder

is_initialised(){
    [ -f "$WORK/timestamp" ]
}

has_changed(){
    find "$SOURCE" -cnewer "$WORK/timestamp" | grep -q .
}

update_timestamp(){
    touch "$WORK/timestamp"
}

if ! is_initialised; then
    do_create_zip && update_timestamp || do_show_error
elif has_changed; then
    do_update_zip && update_timestamp || do_show_error
else
    echo "Nothing to do :)"
fi

【讨论】:

  • 如此简洁和巧妙——简单而优雅。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
  • 2015-03-26
  • 2021-06-20
  • 1970-01-01
相关资源
最近更新 更多