Як використовувати 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), але мені потрібен спосіб ВКЛЮЧИТИ лише файли певного типу / розширення.


BTW, використовуючи pathвище, мабуть, не найкраще ім'я змінної, якщо ви хочете грати з цим першим у оболонці. Якщо ви його використовуєте, ви не зможете використовувати команди і все, оскільки це в основному просто перекрило стандарт PATH. Тому я рекомендую використовувати альтернативне ім'я var, наприклад, fpathзамість цього. тобто while read fpath action fileбудь-яка стандартна команда, яка зазвичай доступна у вашій оболонці, все ще буде.
Батист Матус

це смішно, що немає опції включення.
erandros

Відповіді:


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

@SDsolar Це змінюється. Для мене, я зазвичай працюю 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файлів. Це запускається лише один раз або в циклі for?
kurokirasama

Це демон, тому він буде працювати, поки не вийде з ладу або ви його не
вимкнете

Вибачте, пропустив перше запитання. 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

Дякую !! Я спробую це !!
курокірасама

3

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

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

Булево, якщо Sце твердження:

"заключний лист s"

і Jце твердження:

"передостаннє письмо j"

то значення --exclude параметра має семантичний прирівняти not(J and S), які по законам Де Моргана є not(J) or not(S).

Ще одна потенційна проблема полягає в тому, що в zsh , $pathє вбудованої змінної , що представляє еквівалент на масив $PATH, так що while read path ...лінія буде повністю зіпсувати $PATHі викликати все , щоб стати unexecutable з оболонки.

Тому правильний підхід такий:

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.