在使用rsync时忽略正在使用的文件(正在写入)

我有一个SFTP服务器,客户端不断上传大文件。 定期,我想复制所有完整 (完全上传)的文件到另一台机器进行处理。 我不想复制正在写入的文件。 有没有办法做到这一点? 我目前正在使用rsync,但我打开切换到别的东西。

要检查一个文件当前是否打开(如果当前正在写入的文件肯定是由某个进程打开的话),标准的方法是使用lsof

 if lsof /your/file > /dev/null; then echo "file currently open"; fi 

您可以使用此代码片段来筛选只有未打开的文件的结果,并使用它们来提供rsync:

 find . -type f -exec sh -c 'if ! lsof `readlink -f {}` > /dev/null; then echo `basename {}`; fi' \; | tr '\n' '\0' | rsync -avz --from0 --files-from=- ./ user@host:destination/ 

一些说明:

  • readlink -f需要具有文件的完整path,lsof只接受完整path
  • tr '\n' '\0'模拟find -print0

这里的一个挑战是确定文件是否仍然开始写入。 没有完美的方法来做到这一点。 我认为你可以做的最好的方法就是简单地检查文件上最后修改的时间戳,并且只复制那些几分钟内没有被修改的文件。

rsync本身不能做到这一点,但是你可以把它和find-command结合起来:

 cd /path/to/directory/with/files find ./ -type f -mmin +5 -print0 | rsync --archive --verbose --from0 --files-from=- ./ yourotherserver:targetdir/ 

要打破这个命令,它做了两件事:

  1. 它使用find ./ -type f -mmin +5 -print0来标识至less5分钟没有被修改的所有文件。
  2. 然后使用--from0--files-from参数将此列表提供给rsync 。 这将使rsync只考虑find文件。