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

Сценарий Bash: отслеживание горячей папки и частичных файлов

У меня есть клиент, который загружает файлы через FTP, я создал сценарий, который в основном отслеживает папку ftp и перемещает файл на производственную машину. Как я могу проверить, полностью ли передан файл от клиента через ftp, прежде чем запускать scp команда, чтобы избежать передачи частичных файлов?

Вы не сможете сделать это правильно из bash без помощи клиента.

На стороне FTP-сервера несколько FTP-серверов имеют методы для запуска программы после завершения загрузки (она могла быть завершена или клиент мог быть отключен, FTP-сервер не имеет возможности узнать, действительно ли это сделано или нет).

Чтобы сделать это правильно, лучшее решение - попросить клиента загрузить файл с временным именем, а затем переименовать файл, как только он будет завершен, на правильное имя. Затем вы исключаете из обработки все файлы с именем «something.tmp». В противном случае попросите клиента загрузить файл блокировки с нулевым байтом, загрузить реальный файл, а затем удалить файл блокировки. Затем вы можете проверить наличие файла блокировки

filelist = ...
if [ -e /home/ftp/incoming/lockfile ]; then exit; fi
... process $filelist ...

Если клиент загружает много, то файл блокировки может присутствовать каждый раз, когда вы запускаете свой скрипт, и ничего не будет сделано. В этом случае вам нужно будет сравнить временные метки файлов с файлом блокировки. Файлы старше файла блокировки должны быть полными:

for f in ...; do
    if [ ! -e /home/ftp/incoming/lockfile -o $f -ot /home/ftp/incoming/lockfile ]; then
         ... process $f
    fi
done

Если ни ваш FTP-сервер, ни ваш клиент не будут участвовать вместе с вами, вы можете сделать что-то вроде

  1. создать список файлов и размеров файлов.
  2. Сравните этот список с предыдущим списком файлов
  3. обрабатывать файлы в текущем списке, которые идентичны файлам в предыдущем списке
  4. сохранить текущий список файлов поверх предыдущего списка
  5. подождите 5 минут, затем вернитесь к 1.

Файлы, которые не стали больше за 5 минут, вероятно, так же готовы, как и собираются. Делая это в bash оставлен в качестве упражнения для читателя.

Решение, которое я использую (которое, по общему признанию, не является пуленепробиваемым, но до сих пор работало для меня в 100% случаев), заключается в том, чтобы запрашивать размер файла каждые 10 секунд, и если он не изменился с момента последнего запроса, предположим, что это готово и начинаем перенос.

Конечно, возможно, что в сети может быть 10+ секундный всплеск, из-за которого он не завершил передачу всего, но это довольно редкое явление, и для этого нужны контрольные суммы, такие как MD5.

Если ваша ОС поддерживает это, вы можете взглянуть на врезаться. События, которые можно отслеживать, определены в Incrontab Возможно событие, которое вы ищете

IN_CLOSE_WRITE Файл, открытый для записи, был закрыт (*)

или в сочетании с

IN_CREATE Файл / каталог, созданный в наблюдаемом каталоге (*)

Обратите внимание, что

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