Выполнить команду при изменении файла

9

У меня есть сценарий, в котором я загружаю файлы .csv в определенную папку, / tmp / data_upload, каждый день, и старые файлы заменяются новыми.

Мне нужно запустить скрипт Python после загрузки данных. Для этого у меня есть идея создать задание cron и отслеживать изменения в файле. Я пытался использовать inotify, но я не очень в области Unix. Как я могу это сделать?

Мне нужно выполнить скрипт test.py, как только в папке загрузки появится изменение даты файла, например, / tmp / data_upload.

Alex
источник
Вы смотрели на eradman.com/entrproject , сами не пробовали, но похоже, что это может быть связано.
OO
К вашему сведению, в Python есть inotifyбиблиотеки. Смотрите один из моих ответов здесь для примера: askubuntu.com/a/939392/295286
Сергей Колодяжный,

Ответы:

10

Вам может понадобиться incrond (inotify cron daemon), который будет отслеживать изменения в файлах и затем выполнять сценарии.

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

Пример для вашего случая, вы можете создать файл /etc/incron.d/data_uploadс содержимым

/tmp/data_upload IN_CREATE,IN_MODIFY /path/to/test.py 
victoroloan
источник
2
Хотя это может теоретически ответить на вопрос, было бы предпочтительным включить сюда основные части ответа и предоставить ссылку для справки.
Джеральд Шнайдер
Спасибо за напоминание, я добавил контекст для ссылки.
Виктор
Спасибо за ответ, просто чтобы проверить шаги после установки incrontab, выполните shoudl incrontab -eот имени пользователя root и включите эту строку /tmp/data_upload IN_CREATE,IN_MODIFY test.py ? так, чтобы проверить, как только я загружаю новый файл, он должен выполнить файл test.py? где я должен разместить файл test.py? я должен предоставить абсолютный путь для этого?
Alex
1
Я думаю, будет лучше поставить абсолютный путь для вашего сценария. Вы также можете проверить cron или системный журнал, если скрипт кажется не работает
victoroloan
Можете ли вы также документировать, к какому файлу вы обращаетесь с помощью блока кода, люди, не знакомые с синтаксисом Incrond (как я), могут подумать, что они ссылаются на команду, которую вы должны выполнить в командной строке
Ferrybig
0

В watchexec( https://crates.io/crates/watchexec ) утилита командной строки звучит как именно то , что вам нужно, хотя я считаю , чтобы установить его , вы должны были бы иметь утилиты сборки ржавчины , установленных на вашем компьютере, так что может быть dealbreaker

Бен Сандин
источник
1
Я люблю использовать программное обеспечение, написанное на ржавчине, потому что вы знаете, что оно не было заброшено в 2004 году или что-то в этом роде. Это почти должно быть новым.
Натаниэль
0

Мой общий подход заключается в том, чтобы возиться с классической findутилитой Unix . Например, команда

find /tmp/upload_data/*.csv -mtime -1 -exec /home/myname/test.py

найдет любые .csvфайлы /tmp/upload_data, которые были изменены менее одного дня назад, и запустит ваш, test.pyесли найдет какие-либо. Конечно, если ваш test.pyфайл находится в каком-то другом каталоге, вы хотите соответствующим образом обновить свой путь к нему.

Если вы выполняете свою cronработу чаще, чем раз в день, вы можете использовать mminопцию, findчтобы указать максимальное время с момента изменения в минутах. Например,

find /tmp/upload_data/*.csv -mmin -60 -exec /home/myname/test.py

будет искать .csvфайлы, которые были изменены менее 60 минут назад - полезно, если cron запускает задание ежечасно.

Два справедливых предупреждения в порядке: во-первых, это не поймает .csvфайлы, которые вы полностью удалили. Вы можете проверить это отдельно. Во-вторых, у меня не было времени проверить это. Ожидайте опечаток в моем коде, которые вам придется отлаживать самостоятельно.

Томас Бланкенхорн
источник
1
Какой -cmdсинтаксис? IIRC findпринимает -exec cmd ;...
Д. Бен Кнобл
Я пробовал этот, прежде чем опубликовать этот вопрос, он не работает должным образом на 2-й 3-й последовательный запуск заданий Cron
Алекс
@D. Бен Нобл: Ты прав. Я перепутал команды find-internal с командами оболочки. Исправлена. Спасибо за исправление!
Томас Бланкенхорн