Тази статия ще ви покаже как Inotify се използва за проследяване на създаването, изтриването или модификацията на файлове и директории на файловата система Linux.
За да наблюдавате конкретен файл или директория с помощта на Inotify, изпълнете следните стъпки:
- Създайте екземпляр за инотификация с помощта на inotify_init ()
- Добавете пълния път на директорията или файла, който да наблюдавате и събитията, които да наблюдавате, използвайки функцията inotify_add_watch (). В същата функция ние посочваме кои събития (ON CREATE, ON ACCESS, ON MODIFY и т.н.), промените във файловете или промените в директорията трябва да бъдат наблюдавани.
- Изчакайте да се случат събития и прочетете буфера, който съдържа едно или повече настъпили събития, като използвате Прочети() или изберете ()
- Обработете случилото се събитие, след това се върнете към стъпка 3, за да изчакате още събития, и повторете.
- Премахнете дескриптора на часовника с помощта на inotify_rm_watch ()
- Затворете екземпляра за инотификация.
Сега ще видим функциите, които се използват за Inotify API.
Заглавен файл: sys / inotify.з
inotify_init () функция:
Синтаксис: int inotify_init (void)
Аргументи: Няма аргументи.
Връщани стойности: При успех функцията връща нов дескриптор на файл, при неуспех функцията връща -1.
inotify_add_watch () функция:
Синтаксис: int inotify_add_watch (int fd, const char * pathname, uint32_t маска)
Аргументи:
Тази функция отнема три аргумента.
1ул аргумент (fd) е дескриптор на файл, който се отнася до екземпляра за инотификация (върната стойност на inotify_init () функция) .
2nd аргументът е пътят към директорията или файла, който се наблюдава.
3rd аргументът е битова маска. Битовата маска представлява събитията, които се наблюдават. Можем да гледаме едно или повече събития, използвайки побитово ИЛИ.
Възвръщаеми стойности: При успех функцията връща дескриптор за наблюдение, а при неуспех функцията връща -1.
inotify_rm_watch () функция:
Синтаксис: int inotify_rm_watch (int fd, int32_t wd)
Аргументи:
Тази функция взема два аргумента.
1ул аргумент (fd) е дескриптор на файл, който се отнася до екземпляра за инотификация (върната стойност на inotify_init () функция) .
2nd аргумент (wd) е дескриптор на часовник (върната стойност на inotify_add_watch () функция) .
Възвръщаеми стойности: При успех функцията връща 0, при неуспех функцията връща -1.
Ние използваме Прочети() функция (декларирана в unistd.з заглавна част файл), за да прочете буфера, в който се съхранява информацията за настъпилите събития под формата на inotify_event структура. The inotify_event структурата е декларирана в sys / inotify.з заглавен файл:
struct inotify_eventint32t wd;
uint32_t маска;
uint32_t бисквитка;
uint32_t len;
char име [];
The inotify_event Структурата представлява събитие на файлова система, върнато от системата за инотификация и съдържа следните членове:
- wd: Гледайте дескриптор (възвръщаема стойност на inotify_add_watch () функция)
- маска: Битова маска, която включва всички видове събития
- бисквитка: Уникален номер, който идентифицира събития
- пост: Брой байтове в полето за име
- име: Име на файла или директорията, в които се е случило събитието
По-долу е даден работещ пример, използващ Inotify API:
Инотифицирайте.c файл:
#include#include
#include
#include
#include
#include
#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_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 ();
if (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);
ако (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 * събитие = (struct inotify_event *) & буфер [i];
if (event-> len)
if (event-> mask & IN_CREATE)
if (event-> mask & IN_ISDIR)
printf ("Директорията% s беше създадена.\ n ", събитие-> име);
друго
printf ("Файлът% s беше създаден.\ n ", събитие-> име);
иначе ако (събитие-> маска & IN_DELETE)
if (event-> mask & IN_ISDIR)
printf ("Директорията% s беше изтрита.\ n ", събитие-> име);
друго
printf ("Файлът% s беше изтрит.\ n ", събитие-> име);
иначе ако (събитие-> маска & IN_MODIFY)
if (event-> mask & IN_ISDIR)
printf ("Директорията% s беше променена.\ n ", събитие-> име);
друго
printf ("Файлът% s беше променен.\ n ", събитие-> име);
i + = EVENT_SIZE + събитие-> лен;
Изход:
За да изпълним програмата и да видим изхода, първо трябва да отворим два терминала. За стартиране на програмата се използва един терминал Инотифицирайте.° С. Във втория терминал отиваме към пътя, който се наблюдава от Инотифицира.° С. Ако създадем директория или файл, модифицираме файл или изтрием директория или файл, ще ги видим на първия терминал.
В Инотифицирайте.° С например unistd.з заглавният файл се използва за Прочети() и близо() функция, stdlib.з заглавният файл се използва за изход () функция, сигнал.з заглавният файл се използва за сигнал () функция и SIG_INT макрос (Вижте обработка на сигнала за подробности) и fcntl.з заглавният файл се използва за fcntl () функция.
Ние декларираме fd (инотифицира екземпляр) и wd (watch descriptor) като глобални променливи, така че тези променливи да са достъпни от всички функции.
The fcntl () функция се използва така, че когато четем с помощта на fd дескриптор, нишката няма да бъде блокирана.
След това добавяме часовник с помощта на inotify_add_watch () функция. Тук предаваме fd, пътя на директорията, която ще се гледа, и маската. Можете да предадете маската на събитията, които искате да наблюдавате, използвайки побитово ИЛИ.
Сега прочетете буфера. Информация за едно или повече събития се съхранява в буфера. Можете да обработвате всички събития едно по едно, като използвате цикъла. Можете да проверите събитието-> маска, за да знаете кой тип събития са се случили.
Използваме безкраен цикъл докато непрекъснато проверяваме кога са настъпили събития. Ако не са се случили събития, функцията read () се връща с 0. Връщаната стойност на функцията read () се съхранява в променливата за дължина. Когато стойността на променливата за дължина е по-голяма от нула, са настъпили едно или повече събития.
Ние използваме SIG_INT сигнал (натиснете Ctrl + C), за да излезете от процеса. Когато натиснете Ctrl + C, sig_handler () се извиква функция (Вижте обработка на сигнала за подробности). Тази функция премахва дескриптора на часовника, затваря екземпляра за инотификация fd, и излиза от програмата.
Заключение
Можете да използвате Inotify API във вашите собствени приложения за мониторинг, отстраняване на грешки, автоматизация и други, по ваш собствен начин. Тук видяхме потока на изпълнение на Inotify API.