Использование inotify для отслеживания всех файлов в системе

Вопрос:

Можно ли использовать inotify для надежной записи файлов в системе [linux]?

Подробности:

Я пытаюсь использовать inotifywait для отслеживания перемещений пользователей (в настоящее время используется bash, но это было предложено что я перехожу на язык сценариев). В конечном итоге я хочу добавить новые файлы в базу данных при создании (create, moved_from), обновить существующие строки в базе данных при изменении файла (modify, attrib, move_to) и, наконец, удалить строку при удалении файла (delete). Однако я сталкиваюсь со многими проблемами, так как даже такое, казалось бы, простое действие, как сохранить, генерирует много сообщений inotifywait. Обратите внимание на следующие команды и их вывод (обратите внимание, /home/user/ используется исключительно в качестве примера):

Примеры:

Пример 1. Прослушивание создания файла:

$ inotifywait -mr /home/user/ -e create  --format %w:%f:%e:%T --timefmt %T

Нажмите:

$touch test.txt
/home/user/:test.txt:CREATE:21:35:30

Откройте новый файл с помощью vim, затем введите команду :w:

$vim test2.txt
/home/user/:test2.txt:CREATE:21:35:30

Откройте существующий файл с помощью vim, затем введите команду :w:

$vim test2.txt
/home/user/:4913:CREATE:21:35:30
/home/user/:test2.txt:CREATE:21:35:30

Откройте новый файл с помощью gedit и нажмите "Сохранить":

$gedit test3.txt
/home/user/:test3.txt~:CREATE:21:35:30

Откройте существующий файл с помощью gedit и нажмите "Сохранить":

$gedit test3.txt
/home/user/:.goutputstream-HN3ZDW:CREATE:21:35:30
/home/user/:test3.txt~:CREATE:21:35:30

Обратите внимание, что не только два новых файла отображаются как созданные (4913 и .goutputstream-HN3ZDW), но и единственный создаваемый файл — test3.txt~, а не test3.txt, хотя файл test3.txt создается при проверке с помощью команда ls. Для полноты приведем приведенный выше пример, но с несколькими дополнительными параметрами.

Пример 1. Прослушивание создания, изменения, удаления и перемещения файла:

$ inotifywait -mr /home/user/ -e create -e modify -e delete -e moved_to -e moved_from --format %w:%f:%e:%T --timefmt %T

Нажмите:

$touch test.txt
/home/user/:test.txt:CREATE:21:35:30

Откройте новый файл с помощью vim, затем введите команду :w:

$vim test2.txt
/home/user/:test2.txt:CREATE:22:12:32

Откройте существующий файл с помощью vim, затем введите команду :w:

$vim test2.txt
/home/user/:4913:CREATE:22:04:35
/home/user/:4913:DELETE:22:04:35
/home/user/:test2.txt:MOVED_FROM:22:04:35
/home/user/:test2.txt~:MOVED_TO:22:04:35
/home/user/:test2.txt:CREATE:22:04:35
/home/user/:test2.txt~:DELETE:22:04:35

Откройте новый файл с помощью gedit и нажмите "Сохранить":

$gedit test3.txt
/home/user/:test3.txt~:CREATE:21:35:30

Откройте существующий файл с помощью gedit и нажмите "Сохранить":

$gedit test3.txt
/home/user/:.goutputstream-0WQ2DW:CREATE:22:06:34
/home/user/:test3.txt~:CREATE:22:06:34
/home/user/:.goutputstream-0WQ2DW:MOVED_FROM:22:06:34
/home/user/:test3.txt:MOVED_TO:22:06:34

В основном мой вопрос: «Можно ли использовать inotify для обновления файла в базе данных»? Например, если пользователь редактирует файл и сохраняет его, я хочу, чтобы он отражался в базе данных как обновление этого файла, а не новый файл, заменяющий совершенно другой файл. Любая помощь будет принята с благодарностью, даже если это предложение, указывающее мне в другом направлении.


person puk    schedule 10.05.2012    source источник


Ответы (1)


inotify говорит вам, что происходит, как это происходит.

Gedit, как и большинство редакторов, сохраняет, сначала записывая временный файл, а затем перемещая этот файл на место. Это позволяет избежать перезаписи файла недописанной версией в случае сбоя редактора или всей системы во время записи файла. Vim использует другой подход (его можно настроить, я не буду здесь вдаваться в подробности — см., например, почему значение inode меняется, когда мы редактируем в редакторе «vi»?): он сначала создает временный файл резервной копии, а затем записывает новый файл.

Если вы хотите, чтобы они записывались как одно событие редактирования, вам придется выполнить некоторое распознавание образов в четном журнале. Последовательность создания-записи-перемещения, которая заменяет существующий файл, и последовательность создания-перемещения-создания-удаления, как в vim, были бы архетипическими шаблонами. Обратите внимание, что шаблон может чередоваться с другими событиями.

У меня есть подозрение, что есть лучший способ сделать то, что вы хотите сделать, но я не понимаю, что вы пытаетесь сделать. Если вы пытаетесь регистрировать действия пользователя, вы уже нашли способ, но есть более простые способы: loggedfs или подсистема аудита. Если вы хотите сохранить резервную копию всех версий файлов, либо подключите редактор к системе контроля версий (это позволяет пользователям контролировать, что копируется), либо используйте файловая система управления версиями, например copyfs. Вы даже можете хранить файлы непосредственно в базе данных, используя файловую систему, например mysqlfs или postgresqlfs (правда, ни один из проектов не выглядит поддерживаемым).

person Gilles 'SO- stop being evil'    schedule 11.05.2012
comment
Спасибо за информацию. относительно распознавание образов, я беспокоюсь, что оно не будет на 100% надежным. То, что я пытаюсь сделать, это сохранить все разрешения пользователей и групп в MySQL, а также все местоположения файлов (не фактические файлы), и я хочу, чтобы все обновления в системе отражались в базе данных. Я посмотрю на mysqlfs. - person puk; 11.05.2012
comment
@puk Хорошо, тогда mysqlfs, copyfs и тому подобное вам не помогут. Loggedfs или журналы аудита — это то, что нужно (их легче использовать, чем журналы inotify). Вы получаете события, как они происходят. Вы придаете этим событиям высокоуровневые значения, но на уровне файловой системы эти значения не имеют аналога: понятие «сохранение файла» известно редактору, но файловая система видит только открытие, запись, переименование и т. д. Поскольку значения высокого уровня исходят от вас, вам необходимо провести анализ, чтобы распознать значимые закономерности в реальных событиях. - person Gilles 'SO- stop being evil'; 11.05.2012
comment
слава богу, страница mysqlfs выглядела так, как будто она была написана в 1992 году. Я посмотрю loggedfs и аудит. Когда вы говорите журналы, я предполагаю, что вы имеете в виду сигналы от inotifywait, верно? Или вы имеете в виду запись в файл журнала? - person puk; 11.05.2012
comment
просто добавьте --exclude '/\..+' и inotify будет игнорировать временные файлы .goutputstream - person ostrokach; 11.07.2015