- Linux отследить изменения файлов
- Работаем с Inotify-tools
- Заключение
- Источники и дополнительные материалы:
- Best way to monitor file system changes in linux
- 3 Answers 3
- MNorin.com
- Блог про Linux, Bash и другие информационные технологии
- Inotify в bash: ловим изменения файловой системы
- Программы inotifywait и inotifywatch
- Как работает inotifywatch
- Как работает inotifywait
- Пишем скрипт, который использует inotify
- Похожие посты:
Linux отследить изменения файлов
Библиотека сайта rus-linux.net
libinotifytools , которая позволяет с легкостью задействовать интерфейс, предоставляемый подсистемой Inotify.
Мы будем использовать операционную систему Ubuntu 11.10. Установка Inotify-tools в ней не займёт много времени. Что касается других дистрибутивов (последних версий), то рассматриваемый пакет утилит доступен из репозиториев для openSUSE 12.1, Debian 6.x, Arch и других.
Запустите терминал или перейдите в консоль, а затем дайте команду:
$ sudo apt-get install inotify-tools
Кстати, если вы обратите внимание, то увидите, что, помимо inotify-tools будет установлен пакет — libinotifytools0. Это та самая библиотека, о которой мы говорили выше, и которая необходима для работы inotify-tools.
Работаем с Inotify-tools
В пакет inotify-tools входят следующие утилиты: inotifywatch и inotifywait . inotifywatch — эта утилита, которая дает представление о том, какую информацию можно получить с помощью подсистемы Inotify, а также осуществляет сбор статистической информации о соответствующих событиях файловой системы (открытие файлов, удаление и т. д. — далее, в этом контексте будут иметься ввиду события Inotify).
Рассмотрим на примерах, как это работает. Откройте терминал и дайте команду:
После чего вы увидите на экране примерно следующее (см. рис. 1)
Рисунок 1. inotifywatch в процессе работы
Это означает, что inotifywatch успешно запущен и осуществляет рекурсивный (опция «-r») сбор информации о действиях с файловой системой в домашнем каталоге текущего пользователя. Например, запустим браузер Mozilla Firefox и закроем его. Далее нажмём в терминале «Ctrl»+»C», чтобы остановить inotifywatch . В итоге мы увидим примерно следующее (см. рис. 2, для увеличения щелкните по рисунку мышкой).
Рисунок. 2. Вывод Inotifywatch
В этом выводе вы можете увидеть к каким файлам обращался Mozilla Firefox во время своей работы.
При помощи опции «-e» можно добиться более гибкого вывода информации от inotifywatch . Так, например, нам необходимо узнать какие файлы или каталоги во время своей работы открывает Mozilla Firefox. Дадим следующую команду:
После этого, запустим Mozilla Firefox, поработаем в нем, а затем закроем. Далее остановим в терминале, как в прошлый раз («Ctrl»+»C»), и работу самой утилиты inotifywatch . В выводе мы уже увидим все лишь три «колонки» — total, open и filename (см. рис. 3).
Рисунок 3. Вывод inotifywatch при использовании опции «-e»
Воспользовавшись справкой для данной утилиты, вы можете увидеть, что inotifywatch способна собирать информацию о довольно большом количестве событий. Получить справку по inotifywatch можно с помощью соответствующего руководства man ( man inotifywatch ), а также указав перед данной командой опцию — «-h».
Итак, inotifywatch не отображает статистику о событиях файловой системы сразу. Но, что делать когда необходимо получать информацию о событиях сразу, как они начинают происходить. Во общем, осуществлять мониторинг. В этом нам поможет вторая утилита из пакета Inotify-tools — inotifywait .
где опция «-m» — указывает осуществлять мониторинг событий, без этой опции inotifywait прекратит работу после первого события; опция «-r» — указывает осуществлять рекурсивный сбор информации о действиях с файловой системой.
А запустив Mozilla Firefox, вы увидите все файлы, к которым обращается браузер, а также, действия, которые он с ними осуществляет (создание временных файлов, обращение к внутренним базам данных sqlite и т.д.).
Для получения справки по работе с inotifywait воспользуйтесь соответствующей страницей руководств, а также используйте опцию «-h».
Заключение
inotify-tools удобный инструмент мониторинга событий файловой системы. Кроме того, в ситуация, когда необходимо получить сведения о файлах и каталогах, к которым обращается та или иная программа, inotify-tools может стать лучшим решением, т. к. имеет небольшой объем и мало зависимостей, а также является интерфейсом для подсистемы ядра — Inotify.
Источники и дополнительные материалы:
2. Проект Inotify-tools на GitHub — https://github.com/rvoicilas/inotify-tools/;
3. Исходный код libinotifytools — https://github.com/rvoicilas/inotify-tools/tree/master/libinotifytools/src;
4. Сайт посвященный libinotifytools — http://inotify-tools.sourceforge.net/api/index.html;
5. К. Вервлоесем. Inotify: Следим за системой // Linux Format. — N 1. — 2011. — с. 80 — 83.
Best way to monitor file system changes in linux
I’m looking at building a file system sync utility that monitors file system activity, but it appears that some of the file system monitoring features in the linux kernel are obsolete or not fully featured. What my research as found dnotify came first with notification has the features of notifying for delete,modify,access,attribs,create,move can determine file descriptor, however is now out dated by inotify and fanotify inotify came out second with notification has the features of notifying access, modify, attrib, close, move, delete, create, etc however it does not give you a file descriptor or process and will be outdated by fanotify fanotify is the latest which informs of access, modify, close, but does not inform of delete or attribs, but does provide file descriptor I need a way of determining the process (e.g. from fd) and things like delete, modify, attribs, etc in order to sync everything, any suggestions? Unfortunately dnotify seems the best but most out-dated
3 Answers 3
You should use a library instead of inotify and friends — something like FAM or Gamin (it’s the same API for both). This will make your program portable to other Unixes.
There’s a good lib providing file descriptors or process with inotify. It has his own C API and the inotifywatch util (good for scripts), all in inotify-tools package.
I strongly disagree that fanotify will outdate inotify.
FAM and gamin are very good server/client options. Both of them use inotify as first option over the outdated dnotify and polls. I prefer gamin.
MNorin.com
Блог про Linux, Bash и другие информационные технологии
Inotify в bash: ловим изменения файловой системы
Inotify — это подсистема ядра Linux, которая позволяет отслеживать изменения файловых систем. Использование этой подсистемы позволяет выполнять определенные действия в том случае если вы создали файл, что-то в него записали, открыли, закрыли, удалили и так далее. Использование этого механизма позволяет избавиться от необходимости вставлять в скрипты проверки с таймаутами при помощи команды sleep. Это упрощает логику скрипта, поскольку нам нужно просто ждать информацию об изменениях файловой системы, а при получении информации о том, что что-то изменилось, выполнить необходимые действия. Давайте рассмотрим пример скрипта, использующего inotify.
Программы inotifywait и inotifywatch
Эти программы как раз и помогут нам обеспечить необходимый функционал отслеживания изменений файловой системы. В Debian и Ubuntu они входят в пакет inotify-tools. Установка пакета:
apt-get install inotify-tools
Как работает inotifywatch
Программа inotifywatch собирает статистику доступа к файловой системе при помощи inotify. По окончании работы программа выводит статистическую информацию в виде таблицы, включающей информацию об общем количестве событий, о количестве событий каждого типа и файле, для которого произошло событие. У неё есть ряд параметров, которые можно использовать для изменения параметров работы программы.
Типы событий для отслеживания:
access | Отслеживаемый файл или файл в отслеживаемой директории был прочитан |
modify | Отслеживаемый файл или файл в отслеживаемой директории был записан |
attrib | Метаданные отслеживаемого файла или файла в отслеживаемой директории были изменены. Сюда включаются изменения времени доступа и изменения, права доступа, расширенные атрибуты и так далее. |
close_write | Отслеживаемый файл или файл в отслеживаемой директории был закрыт после открытия его в режиме записи. Это не говорит о том, что в файл были записаны какие-то данные. |
close_nowrite | Отслеживаемый файл или файл в отслеживаемой директории был закрыт после открытия в режиме только для чтения |
close | Отслеживаемый файл или файл в отслеживаемой директории был закрыт, при этом неважно, в каком режиме он был открыт. Имейте в виду, что это событие рализовано просто прослушиванием обоих событий close_write и close_nowrite, поэтому все события будут выведены именно как одно из них, а не как CLOSE. Этот тип скорее как сокращение для двух других типов событий |
open | Отслеживаемый файл или файл в отслежваемой директории был открыт |
moved_to | Файл или директория были перемещены в отслеживаемую директорию. Это событие возникает даже в том случае, когда файл был перемещен в пределах одной и той же директории |
moved_from | Файл или директория были перемещены из отслеживаемой директории. Это событие возникает даже в том случае, когда файл был перемещен в пределах одной и той же директории |
move | Файл или директория были перемещены из отслеживаемой директории или в неё. Это событие реализовано аналогично событию CLOSE, то есть, скорее как псевдоним для двух типов событий, moved_to и moved_from,поэтому все события будут выведены именно как одно из них, а не как MOVE |
move_self | Отслеживаемый файл или директорию были перемещены. После возникновения этого события файл или директория больше не отслеживается. |
create | Файл или директория были созданы в отслеживаемой директории |
delete | Файл или директория были удалены из отслеживаемой директории |
delete_self | Отслеживаемый файл или директория были удалены. После этого события файл или директория больше не отслеживается. Обратите внимание, что это событие может произойти, даже если оно явно не слушалось. |
unmount | Файловая система, накоторой находится отслеживаемый файл или директория, была отмонтирована. Поле возникновения этого события файл или директория перестает отслеживаться.Обратите внимание, что это событие может произойти, даже если оно явно не слушалось. |
Пример работы программы inotifywatch:
$ inotifywatch -r -t 300 /var/cache Establishing watches. Finished establishing watches, now collecting statistics. total attrib open moved_to filename 182 1 1 180 /var/cache/apt/archives/ 1 0 1 0 /var/cache/apt/
Как работает inotifywait
Программа inotifywait работает несколько иначе. Она ждет возникновения события и выводит информацию об этом событии сразу, не дожидаясь сигнала прерывания.
Параметры inotifywait очень похожи на параметры inotifywatch:
События, которые отслеживаются, точно такие же, как для программы inotifywatch.
Пример работы программы inotifywait:
$ inotifywait /var/cache Setting up watches. Watches established. /var/cache/ OPEN,ISDIR apt
Пишем скрипт, который использует inotify
Прежде всего определимся с условиями задачи, которую нам предстоит решить. Есть некоторые директории, куда пользователи загружают файлы (пусть это будут домашние директории пользователей, /home/ИМЯ-ПОЛЬЗОВАТЕЛЯ). Иногда пользователи эти файлы удаляют, поэтому нам нужно отслеживать изменения и при появлении новых файлов (или новых версий уже существующих файлов) копировать их в директорию /backup/ИМЯ-ПОЛЬЗОВАТЕЛЯ.
Для реализации нам нужно отслеживать изменения файловой системы, на которой находится директория /home, определять, что произошло событие закрытия файла после записи в него, получать директорию, в которой произошло закрытие файла, имя самого файла, определять имя директории, в которую планируется копировать файл, создавать её, если она еще не существует, и, собственно, копировать этот файл в эту директорию.
#!/bin/bash SRC_DIR="/home" DST_DIR="/backup" # Функция, которая будет выполнять необходимые действия # В нашем случае копировать в другую директорию make_action()< # Получаем директорию назначения DIR_TO_COPY_TO=$/$> # Создаем ее, если ее еще не существует mkdir -p $DIR_TO_COPY_TO # Копируем файл cp $1$2 $DIR_TO_COPY_TO > IFS=' ' # Отслеживаем закрытие файлов после записи # Получаем вывод в нужном нам формате inotifywait -e close_write --format '%w %f' -m -r $SRC_DIR |\ ( while read do # Получаем имя директории DIR=$(echo $REPLY | cut -f 1 -d' ') # Получаем имя файла FILE=$(echo $REPLY | cut -f 2 -d' ') # Передаем имена директории и файла в функцию make_action $DIR $FILE done )
Как видите, всё достаточно просто. Если необходимо работать с файлами, имена которых содержат пробелы, вы можете использовать параметр «—csv» и разделять поля по запятой, а не по пробелу, как в примере, или добавить какой-то другой символ в строку шаблона вывода. Основной принцип работы при этом не изменится.