如何使用 rsync 实现轮换方案

如何使用 rsync 实现轮换方案

我有一个不断增长的远程文件目录,我想在rsync它们之前对其进行排序和过滤,目标是始终仅在我的目标目录中保留最新的 N 个文件(即或多或少的轮换方案)。由于rsync似乎没有这方面的选项,我一直在使用“插入任意远程命令”的技术,如下所述:

https://stackoverflow.com/q/950062/787842

我想出了这个命令,我在目标主机上作为 cron 执行:

rsync -vrzO --delete \
    -e ssh <remote_host>:'$(cd <remote_dir> && ls -t $PWD/* | head -n 25)' \
    <destination_dir>

这在第一次时效果很好(即当目标目录为空时):仅复制 25 个最新文件。但是,当窗口“向前滑动”时(即,当新文件的到达应该在本地将旧文件推出时),问题是该--delete选项无法按我的预期工作。我的猜测是,由于过滤掉的远程文件仍然存在(即它们只是被插入的'$(..)'命令暂时隐藏),所以rsync根本无法在本地过滤掉它们。我的理解是否正确,还有更好的方法吗?

答案1

您可以将您的命令模拟为,

rsync -vrzO --delete -e ssh <remote_host>:'<remote_dir>/file1 <remote_dir>/file2' <destination_dir>/ 即替换 的输出cd <remote_dir> && ls -t $PWD/* | head -n 2

rsync--delete适用于目录和您的命令替换正在提供文件列表。所以--delete不工作。

摘自man rsync

- 删除

这告诉 rsync 从接收端删除无关的文件(不在发送端的文件),但仅适用于目录 正在同步。你 必须要求 rsync 发送整个目录(例如“dir”或“dir/”)而不使用目录内容的通配符(例如“dir/*”),因为通配符由shell扩展,rsync因此获得传输单个文件的请求,而不是文件的请求父目录。

答案2

将远程目录挂载到sshfs。然后你就可以把它当作本地目录了。

现在,要按修改时间对文件进行排序,最简单的方法是桀骜全局限定符。目录中最近的 25 个文件是

*(NDom[1,25])

因此,如果您想先复制,请删除目的地的无关文件:

for x in source/*(NDom[1,25]); do
  y=destination/${x:t}
  if [[ ! -e $y || $x -nt $y ]]; then cp -p $x $y; fi
done
destination_files=(destination/*(NDom[1,25]))
if [[ ${#destination_files} -gt 25 ]]; then
  shift $((${#destination_files} - 25)) destination_files
  rm $destination_files
fi

这是在复制之前删除文件的另一种方法。当要复制新文件并且目的地已经有完整的补充文件时,此文件会删除最旧的文件。

destination_files=(destination/*(ND)); destination_count=$#destination_files
for x in source/*(NDom[1,25]); do
  y=destination/${x:t}
  if [[ $destination_count -gt 25 && ! -e $y ]]; then rm destination/*(NDom[-1]); fi
  if [[ ! -e $y || $x -nt $y ]]; then cp -p $x $y; fi
done

(警告:上面的代码是直接在浏览器中输入的,我没有测试。)

相关内容