Назад | Перейти на главную страницу

Inotify и Rsync - не перемещайте файлы до завершения загрузки

Я использую локальный веб-сайт, который загружает файлы на мой сервер. Используя демон Inotify, я прослушиваю изменения файлов в определенной папке (той, в которую я загружаю) и выполняю сценарий, который перемещает эти файлы в другую папку с помощью rsync. Однако моя проблема в том, что rsync перемещает файлы до того, как они будут полностью загружены, поэтому их размер составляет 0 КБ. Раньше я использовал mv, и mv каким-то образом удалось дождаться завершения загрузки перед перемещением, но мне нужно было использовать rsync, потому что mv не будет записывать в существующие непустые папки.

Любые идеи?

Вот мой сценарий, который выполняется при создании inotify:

#!/bin/sh

cd the_folder_which_is_watched_by_inotify

rsync -vh * /where_the_files_are_moved_to

echo "Files have been moved"

Вам следует настроить демон inotify для запуска rsync только на CLOSE_WRITE и MOVE_FROM/MOVE_TO комбо-события.

Если вы слушаете CREATE и / или MODIFY события, вы закончите rsync, вызываемым при записи файла, что приведет к повреждению / пустой копии.

Причина, по которой mv, вероятно, будет работать, заключается в том, что файл на самом деле будет тот же файл. Таким образом, процесс загрузки будет записывать данные в заданный индексный дескриптор, а команда mv просто обновляет источник и места назначения, чтобы индексный дескриптор находился в другом месте. Но любые программы с открытым дескриптором файла смогут продолжить работу с этим индексным дескриптором, поэтому вы можете переместить ссылку туда, где захотите.

Что вы могли бы сделать, так это использовать rsync --link-dest вариант. Получение правильные пути - это сложно поскольку --link-dest требуется относительный путь к источнику с точки зрения места назначения. Но это должно привести к тому, что rsync сделает жесткие ссылки на файл. То есть и источник, и место назначения должны ссылаться на один и тот же индексный дескриптор.