Почему inotifywatch не обнаруживает изменения в добавленных файлах?

14

Я пытаюсь отслеживать мою /tmpпапку на предмет изменений, используя inotifywatch:

sudo inotifywatch -v -r /tmp

После создания пары файлов ( touch /tmp/test-1 /tmp/test-2) я завершаю inotifywatch(с помощью Ctrl- Cкоторый показывает мне следующую статистику:

Establishing watches...
Setting up watch(es) on /tmp
OK, /tmp is now being watched.
Total of 39 watches.
Finished establishing watches, now collecting statistics.
total  attrib  close_write  open  create  filename
8      2       2            2     2       /tmp/

Вывод выводит только статистику, но не те файлы, которые я ожидал (как здесь или здесь ). Я пробовал различные типы доступа ( с помощью cat, mktempи т.д.), но это то же самое.

Я что-то пропустил? Это потому, что я на VPS и что-то ограничено?

ОС: Debian 7.3 (инструменты inotify) на VPS

kenorb
источник

Ответы:

14

Это связано с тем, как вы используете inotifywatch, и как работает сам инструмент. Когда вы запускаете inotifywatch -r /tmp, вы начинаете смотреть /tmpи все файлы, которые уже есть в нем. Когда вы создаете файл внутри /tmp, метаданные каталога обновляются, чтобы содержать номер индекса нового файла, что означает, что изменение происходит /tmp, а не /tmp/test-1. Кроме того, так /tmp/test-1как не было там, когда inotifywatchначалось, на нем нет inotifyчасов. Это означает, что любое событие, которое происходит с файлом, созданным после помещения часов, не будет обнаружено . Возможно, вы поймете это лучше, если увидите это сами:

$ inotifywatch -rv /tmp &
Total of n watches.
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

Если вы включили механизм трассировкиinotify_add_watch(2) , последняя команда выдаст вам количество часов, установленных inotifywatch. Это число должно быть таким же, как и inotifywatchсамо по себе. Теперь создайте файл внутри /tmpи проверьте снова:

$ inotifywatch -rv /tmp &
Total of n watches.
$ touch /tmp/test1.txt
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

Число не увеличится, что означает, что новый файл не просматривается. Обратите внимание, что поведение будет другим, если вместо этого вы создадите каталог:

$ inotifywatch -rv /tmp &
Total of n watches.
$ mkdir /tmp/test1
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n + 1

Это связано с тем, как -rкоммутатор ведет себя :

-r, --recursive: [...] Если в наблюдаемых каталогах создаются новые каталоги, они будут автоматически отслеживаться.

Edit: я немного запутался между вашими двумя примерами, но в первом случае , часы правильно размещены , так как вызовы пользователя inotifywatchна ~/*(который раскладывается, см комментарий don_crissti здесь ). Домашний каталог также отслеживается, потому что ~/.*содержит ~/.. Теоретически, он также должен содержать ~/.., что в сочетании с -rпереключателем должно привести к просмотру всей системы.

Тем не менее, это возможно , чтобы получить имя файла , запускающий создать событие в наблюдаемом каталоге, но я предполагаю , inotifywatchне получить эту информацию (он сохраняется немного глубже , чем имя каталога). inotify-toolsпредоставляет другой инструмент под названием inotifywait, который может вести себя примерно так же inotify-watch, и предоставляет больше опций вывода (включая то %f, что вы ищете здесь):

inotifywait -m --format "%e %f" /tmp

Со страницы руководства :

--format <fmt>Вывод в указанном пользователем формате с использованием printf-подобного синтаксиса. [...] Поддерживаются следующие преобразования:

%f: когда событие происходит в каталоге, оно будет заменено именем файла, вызвавшего событие .

%e: заменяется событием (ями), которые произошли, через запятую.

Кроме того, -mопция (монитор) будет продолжать inotifywaitработать после первого события, которое будет воспроизводить поведение, очень похожее на inotifywatch«s».

Джон У. Смит
источник
1
.bashrcв примере @ serverfaultне появляется в статистике, потому что пользователь рекурсивно контролирует свой домашний каталог, а потому что path/.*расширяется, и в результате для всех .files в path/( .bashrcвключенных) устанавливается наблюдение . Команда, используемая OP, никогда не будет выводить имена файлов, поскольку для них установлены часы /tmpи любые подкаталоги, поэтому статистика будет относиться только к /tmpподкаталогам и их подкаталогам (т. Е. Вы увидите, что к файлам обращались / перемещали / и т. Д., Но не сообщали вам их имена).
don_crissti
@don_crissti Ой, я перепутал два примера, приведенных ОП. Я отредактировал свой ответ, спасибо!
Джон У. С. Смит,
Спасибо, это было полезно. Вот моя команда , чтобы показать содержимое всех вновь созданных тест * файлы в /tmp: inotifywait -m --format "%f" /tmp | grep --line-buffered ^test | xargs -L1 -I% sudo cat /tmp/% 2> /dev/null.
Кенорб
Также: « Это означает, что любое событие, которое происходит в файле, созданном после помещения часов, не будет обнаружено». Любое событие (даже создание файла) будет обнаружено, потому что часы УЖЕ установлены для каталога, в котором они находятся, и это отражено в статистике для этого конкретного каталога. См. inotifywatchВывод в вопросе OP: есть 2 createсобытия (поэтому они обнаружены), но, поскольку inotifywatchпросматривает каталог (+ любые подкаталоги), статистика относится только к этим / этим каталогам.
don_crissti
1
Я не думаю, что мы находимся здесь на одной волне ... man inotify: When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.Кроме того, man inotifywatchясно, какие события просматриваются: EVENTS>> ... Просмотренный файл или файл в просматриваемой директории был доступен / закрыт / открыт / и т. д. (означает включение событий "которые происходят в файле" ). События для файла, созданного после установки наблюдения на родительском каталоге, БУДУТ обнаружены и отражены в inotifywatchстатистике (в нем НЕ будет указано, для каких файлов произошли эти события).
don_crissti