Как использовать inotifywait для просмотра каталога для создания файлов определенного расширения


21

Я видел этот ответ .

Вы должны рассмотреть возможность использования inotifywait, например:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

Мой вопрос заключается в том, что приведенный выше скрипт следит за каталогом для создания файлов любого типа, но как мне изменить inotifywaitкоманду, чтобы она сообщала только тогда, когда файл определенного типа / расширения создан (или перемещен в каталог) - например, он должен сообщить, когда любой .xmlфайл создан.

ЧТО Я ПОПЫТАЛ

Я выполнил inotifywait --helpкоманду и прочитал параметры командной строки. Он имеет --exclude <pattern>и --excludei <pattern>команды для ИСКЛЮЧЕНИЯ файлов определенных типов (с помощью regEx), но мне нужен способ ВКЛЮЧИТЬ только файлы определенного типа / расширения.


Кстати, использование pathвыше, вероятно, не лучшее имя переменной, если вы хотите поиграть с этим первым в оболочке. Если вы используете его, то вы не сможете использовать команды и все остальное, поскольку это в основном просто переопределило стандарт PATH. Поэтому я рекомендую использовать альтернативное имя var, например, fpathвместо. т.е. while read fpath action fileлюбая стандартная команда, обычно доступная из вашей оболочки, все равно будет.
— Креститель Матус

это довольно смешно, что нет опции включения.
— Эрандрос

Ответы:


17

Как я могу изменить команду inotifywait, чтобы сообщать только при создании файла определенного типа / расширения

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

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        if [[ "$file" =~ .*xml$ ]]; then # Does the file end with .xml?
            echo "xml file" # If so, do your thing here!
        fi
    done

2
Это работает, и я проверил это с inotifywait.
— TheBetterJORT

1
Как вы управляете этим? Это однократная команда, или она должна выполняться в цикле или что-то в этом роде? Возможно, как часть incron(я надеюсь, что нет).
— SDsolar

@ SDolar Это меняется. Для меня, я обычно работаю inotifyлибо с nohupили запустить его с помощью пользовательской Systemd службы. Чаще всего последний.
— Maulinglawns

9

Используйте двойной минус:

inotifywait -m --exclude "[^j][^s]$" /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
    done

Это будет включать только файлы JavaScript


1
Хорошо, мне нравится, что он смещает фильтрацию, inotifywaitа не генерирует огромный вывод для всех файлов и фильтрует впоследствии (как в другом ответе). Не пробовал, но думаю, что это будет работать немного быстрее.
— TMG

Это именно то, что я искал. Как изменить --excludeвход для просмотра .extфайлов. Это выполняется только один раз или в цикле?
— Курокирасама

Это демон, поэтому он будет работать до тех пор, пока он не выйдет из строя или не выключится :)
— Jonas Earendel

Извините, пропустил первый вопрос. inotifywait -m --exclude "[^.][^e][^x][^t]$" /home/jonas/Skrivbord/test -e create -e moved_to | while read path action file; do echo "The file '$file' appeared in directory '$path' via '$action'" done Я уверен, что регулярное выражение может быть оптимизировано, но этот ребенок работает :)
— Jonas Earendel

Thanxs !! Я попробую это !!
— Курокирасама

3

Хотя двойной отрицательный подход предыдущего ответа является хорошей идеей, поскольку (как отметил TMG) ​​он действительно переносит работу по фильтрации inotifywait, но он не верен.

Например, если файл заканчивается, asон не будет совпадать, [^j][^s]$потому что последняя буква sне совпадает [^s], поэтому он не будет исключен.

В логических терминах, если Sэто утверждение:

"последнее письмо s"

и Jэто утверждение:

«предпоследнее письмо есть j»

тогда значение --excludeпараметра должно семантически приравняться not(J and S), что по законам де Моргана является not(J) or not(S).

Другая потенциальная проблема заключается в том zsh, что in , $pathявляется встроенной переменной, представляющей эквивалент массива $PATH, поэтому while read path ...строка полностью испортится $PATHи приведет к тому, что все станет неисполнимым из оболочки.

Поэтому правильный подход:

inotifywait -m --exclude "[^j].$|[^s]$" /path -e create -e moved_to |
    while read dir action file; do
        echo "The file '$file' appeared in directory '$dir' via '$action'"
    done

Обратите внимание на то, .что необходимо после того, [^j]чтобы убедиться, что сопоставление применяется в предпоследней позиции, а также что |символ (представляющий логическое ИЛИ, упомянутое выше) не должен быть экранирован здесь, потому что --excludeпринимает расширенные регулярные выражения POSIX.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.