Использование inotify для мониторинга каталога, но не работает на 100%

10

Я написал скрипт bash для мониторинга определенного каталога /root/secondfolder/:

#!/bin/sh

while inotifywait -mr -e close_write "/root/secondfolder/"
do
    echo "close_write"
done

Когда я создаю файл с именем fourth.txtin /root/secondfolder/и записываю в него содержимое, сохраняю и закрываю его, он выдает следующее:

/root/secondfolder/ CLOSE_WRITE,CLOSE fourth.txt

Однако, это не повторяет "close_write". Это почему?

mib1413456
источник

Ответы:

16

inotifywait -m режим «монитор» : он никогда не выходит. Оболочка запускает его и ждет, пока код завершения не определит, следует ли запускать тело цикла, но этого не происходит.

Если вы удалите -m, это будет работать:

while inotifywait -r -e close_write "/root/secondfolder/"
do
    echo "close_write"
done

производит

Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/root/secondfolder/ CLOSE_WRITE,CLOSE bar
close_write
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
...

По умолчанию inotifywait будет «выходить после того, как произойдет первое событие», что и требуется в условии цикла.


Вместо этого вы можете прочитать стандартный вывод inotifywait:

#!/bin/bash

while read line
do
    echo "close_write: $line"
done < <(inotifywait -mr -e close_write "/tmp/test/")

Этот (bash) скрипт будет считывать каждую выходную строку inotifywaitкоманды в $lineпеременную внутри цикла, используя подстановку процесса . Это позволяет избежать настройки рекурсивных часов каждый раз вокруг цикла, что может быть дорого. Если вы не можете использовать Баш, вы можете трубы команды в петлю вместо: inotifywait ... | while read line .... inotifywaitпроизводит одну строку вывода для каждого события в этом режиме, поэтому цикл запускается один раз для каждого события.

Майкл Гомер
источник
2
Подача команды в цикл работает, спасибо!
mib1413456