Эта статья покажет вам, как Inotify используется для отслеживания создания, удаления или изменения файлов и каталогов файловой системы Linux.
Чтобы отслеживать определенный файл или каталог с помощью Inotify, выполните следующие действия:
- Создайте экземпляр inotify, используя inotify_init ()
- Добавьте полный путь к каталогу или файлу для отслеживания и событий для наблюдения с помощью функции inotify_add_watch (). В этой же функции мы указываем, какие события (ON CREATE, ON ACCESS, ON MODIFY и т. Д.), изменения в файлах или каталогах должны отслеживаться.
- Подождите, пока произойдут события, и прочитайте буфер, содержащий одно или несколько произошедших событий, используя читать() или же Выбрать()
- Обработайте произошедшее событие, затем вернитесь к шагу 3, чтобы дождаться других событий, и повторите.
- Удалите дескриптор часов, используя inotify_rm_watch ()
- Закройте экземпляр inotify.
Теперь мы увидим функции, которые используются для Inotify API.
Заголовочный файл: sys / inotify.час
inotify_init () функция:
Синтаксис: int inotify_init (void)
Аргументы: без аргументов.
Возвращаемые значения: в случае успеха функция возвращает новый дескриптор файла, в случае ошибки функция возвращает -1.
inotify_add_watch () функция:
Синтаксис: int inotify_add_watch (int fd, const char * путь, маска uint32_t)
Аргументы:
Эта функция принимает три аргумента.
1ул аргумент (fd) - это дескриптор файла, который ссылается на экземпляр inotify (возвращаемое значение inotify_init () функция) .
2nd аргумент - это путь к отслеживаемому каталогу или файлу.
3rd аргумент - это битовая маска. Битовая маска представляет наблюдаемые события. Мы можем наблюдать за одним или несколькими событиями, используя побитовое ИЛИ.
Возвращаемые значения: В случае успеха функция возвращает дескриптор часов, в случае неудачи функция возвращает -1.
inotify_rm_watch () функция:
Синтаксис: интервал inotify_rm_watch (интервал fd, int32_t wd)
Аргументы:
Эта функция принимает два аргумента.
1ул аргумент (fd) - это дескриптор файла, который ссылается на экземпляр inotify (возвращаемое значение inotify_init () функция) .
2nd аргумент (wd) - дескриптор наблюдения (возвращаемое значение inotify_add_watch () функция) .
Возвращаемые значения: В случае успеха функция возвращает 0, в случае неудачи функция возвращает -1.
Мы используем читать() функция (объявленная в unistd.час заголовок файл) для чтения буфера, в котором хранится информация о произошедших событиях в виде inotify_event состав. В inotify_event структура заявлена в sys / inotify.час заголовочный файл:
struct inotify_eventint32t wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
название символа[];
В inotify_event Структура представляет собой событие файловой системы, возвращаемое системой inotify, и содержит следующие элементы:
- wd: Дескриптор наблюдения (возвращаемое значение inotify_add_watch () функция)
- маска: Битовая маска, включающая все типы событий
- печенье: Уникальный номер, идентифицирующий события
- len: Количество байтов в поле имени
- название: Имя файла или каталога, в котором произошло событие
Ниже приведен рабочий пример с использованием Inotify API:
Inotify.c файл:
#включать#включать
#включать
#включать
#включать
#включать
#define MAX_EVENTS 1024 / * Максимальное количество событий для обработки * /
#define LEN_NAME 16 / * Предполагая, что длина имени файла
не превышает 16 байт * /
#define EVENT_SIZE (sizeof (struct inotify_event)) / * размер одного события * /
#define BUF_LEN (MAX_EVENTS * (EVENT_SIZE + LEN_NAME))
/ * буфер для хранения данных событий * /
int fd, wd;
void sig_handler (int sig)
/ * Шаг 5. Удалите дескриптор часов и закройте экземпляр inotify * /
inotify_rm_watch (fd, wd);
закрыть (fd);
выход (0);
int main (int argc, char ** argv)
char * path_to_be_watched;
сигнал (SIGINT, sig_handler);
path_to_be_watched = argv [1];
/* Шаг 1. Инициализировать inotify * /
fd = inotify_init ();
если (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) // error checking for fcntl
выход (2);
/* Шаг 2. Добавить часы * /
wd = inotify_add_watch (fd, path_to_be_watched, IN_MODIFY | IN_CREATE | IN_DELETE);
if (wd == - 1)
printf ("Не удалось посмотреть:% s \ n", path_to_be_watched);
еще
printf ("Наблюдение:% s \ n", path_to_be_watched);
в то время как (1)
int i = 0, длина;
буфер символов [BUF_LEN];
/* Шаг 3. Буфер чтения * /
длина = чтение (fd, буфер, BUF_LEN);
/ * Шаг 4. Обработка произошедших событий * /
в то время как я
struct inotify_event * event = (struct inotify_event *) и буфер [i];
if (event-> len)
if (событие-> маска & IN_CREATE)
if (событие-> маска & IN_ISDIR)
printf ("Каталог% s был создан.\ n ", событие-> имя);
еще
printf ("Файл% s был создан.\ n ", событие-> имя);
иначе, если (событие-> маска & IN_DELETE)
if (событие-> маска & IN_ISDIR)
printf ("Каталог% s был удален.\ n ", событие-> имя);
еще
printf ("Файл% s удален.\ n ", событие-> имя);
иначе, если (событие-> маска & IN_MODIFY)
if (событие-> маска & IN_ISDIR)
printf ("Каталог% s был изменен.\ n ", событие-> имя);
еще
printf ("Файл% s был изменен.\ n ", событие-> имя);
я + = РАЗМЕР СОБЫТИЯ + событие-> len;
Выход:
Чтобы выполнить программу и увидеть результат, мы должны сначала открыть два терминала. Один терминал используется для запуска программы Inotify.c. Во втором терминале мы переходим на путь, за которым следит Inotify.c. Если мы создадим какой-либо каталог или файл, изменим любой файл или удалим любой каталог или файл, мы увидим их на первом терминале.
в Inotify.c например, unistd.час заголовочный файл используется для читать() а также Закрыть() функция, stdlib.час заголовочный файл используется для выход() функция, сигнал.час заголовочный файл используется для сигнал () функция и SIG_INT макрос (подробности см. в обработке сигналов), а fcntl.час заголовочный файл используется для fcntl () функция.
Мы заявляем fd (экземпляр inotify) и wd (дескриптор просмотра) как глобальные переменные, чтобы эти переменные были доступны из всех функций.
В fcntl () функция используется для того, чтобы при чтении с помощью fd дескриптор, поток не будет заблокирован.
Затем мы добавляем часы с помощью inotify_add_watch () функция. Здесь мы передаем fd, путь к наблюдаемому каталогу и маску. Вы можете передать маску событий, которые хотите отслеживать, с помощью побитового ИЛИ.
Теперь прочтите буфер. Информация об одном или нескольких событиях хранится в буфере. Вы можете обрабатывать все события одно за другим, используя цикл. Вы можете проверить маску события->, чтобы узнать, какие события произошли.
Мы используем бесконечный цикл while, чтобы постоянно проверять, когда произошли события. Если никаких событий не произошло, функция read () вернется с 0. Возвращаемое значение функции read () сохраняется в переменной длины. Когда значение переменной длины больше нуля, произошло одно или несколько событий.
Мы используем SIG_INT сигнал (нажмите Ctrl + C), чтобы выйти из процесса. Когда вы нажимаете Ctrl + C, sig_handler () вызывается функция (подробности см. в обработке сигналов). Эта функция удаляет дескриптор часов, закрывает экземпляр inotify fd, и выходит из программы.
Заключение
Вы можете использовать Inotify API в своих собственных приложениях для мониторинга, отладки, автоматизации и многого другого по-своему. Здесь мы видели поток выполнения Inotify API.