2012-01-24 5 views
0

Я хочу контролировать папку.inotify проблемы при запуске системы

Каждый раз, когда появляется уведомление, я хочу запустить системную командную строку. Проблемы при использовании системной команды. Каждое новое событие появляется в 3 раза, хотя оно должно появляться один раз. EDIT: Thx для вас. Я нашел ошибку. Система выполнила папку, которая находилась внутри контролируемого foder. поэтому каждый раз, когда я удалял foder в контролируемой папке, событие было напечатано 3 раза.

код -----------

/* 

    Simple example for inotify in Linux. 

    */ 


    #include <sys/inotify.h> 
    #include <stdio.h> 
    #include <string.h> 
    #include <stdlib.h> 

    int main(){ 
     int fd,wd,wd1,i=0,len=0; 
     char pathname[100],buf[1024]; 
     struct inotify_event *event; 

     fd=inotify_init1(IN_NONBLOCK); 
     /* watch /test directory for any activity and report it back to me */ 

`wd=inotify_add_watch(fd,"/home/folder",IN_ALL_EVENTS`); 

     while(1){ 
      //read 1024 bytes of events from fd into buf 
      i=0; 
      len=read(fd,buf,1024); 
      while(i<len){ 
       event=(struct inotify_event *) &buf[i]; 


       /* check for changes */ 
       if(event->mask & IN_OPEN) 
       { // printf("\n %s :was opened\n",event->name); 
        char*path="/home/folder/"; 
        char*file=event->name; 
        int n=sizeof(path)+sizeof(file); 
        char *result=(char *)malloc(512); 
        strcpy(result,path); // copy string one into the result. 
        strcat(result,file); // append string two to the result 
        puts (result); 

        //printf("RESUULT:"); 

        int pp=sizeof(result); 
        char *run="/home/test/./userr "; 
        int l=sizeof(run); 

        char *cmd=(char *)malloc(1000); 
        strcpy(cmd,run); 
        strcat(cmd,result); 
        puts (cmd); 

        system(cmd); 
        printf("\n %s :was opened\n",event->name); 
        //break; 

      } 
       if(event->mask & IN_MODIFY) 
         printf("%s : modified\n",event->name); 

       if(event->mask & IN_ATTRIB) 
         printf("%s :meta data changed\n",event->name); 

       if(event->mask & IN_ACCESS) 
         printf("%s :was read\n",event->name); 

       if(event->mask & IN_CLOSE_WRITE) 
         printf("%s :file opened for writing was closed\n",event->name); 

       // if(event->mask & IN_DELETE) 
       // printf("%s :deleted\n",event->name); 

       /* update index to start of next event */ 
       i+=sizeof(struct inotify_event)+event->len; 
      } 

     } 

    } 

РЕДАКТИРОВАТЬ:

как я могу спать While (1) в течение 1 минуты? SPEEP (60); выталкивает Inotify пустота: была открыта вместо folder1: была открыта, когда я Dropp в Foder в контролируемой папке

./exec

:was opened 
/home/folder/ 
    :file opened not for writing was closed 

Без сна внутри некоторое время (код размещен) у меня есть:

1002_copy :was opened 
/home/folder/1002_copy 
1002_copy :file opened not for writing was closed 
+0

Существует разрыв в первом if() {} блоке. После этого блока i не будет увеличиваться, и он пропустит остальную часть прочитанного. Подсказка: используйте цикл for (;;), который является более понятным. – wildplasser

+0

Я добавил перерыв, потому что мне нужно. но он не работает –

+0

@justAngela Но, а как насчет внешнего while (1) цикла. Это вызовет повторение внутреннего цикла. См. Мой ответ. –

ответ

1

Вы используете команду system() в условии if, которое вызывается каждый раз, когда отображается открытый файл.

Таким образом, он будет работать бесконечно при каждом открытии файла. Вы должны найти способ выйти из цикла.

Когда выполнение достигает разрыва строки, оно выходит из внутреннего, но как насчет внешнего while(1)?

AS ЗАПРОШЕННЫЙ (рабочий код):

#include <sys/inotify.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main(){ 
    int fd,wd,wd1,i=0,len=0; 
    char pathname[100],buf[1024]; 
    struct inotify_event *event; 

    fd=inotify_init1(IN_NONBLOCK); 
    wd=inotify_add_watch(fd,"/tmp/temp",IN_ALL_EVENTS); 
    while(1){ 
     //read 1024 bytes of events from fd into buf 
     i=0; 
     len=read(fd,buf,1024); 
     while(i<len){ 
      event=(struct inotify_event *) &buf[i]; 
      /* check for changes */ 
      if(event->mask & IN_CREATE){ 
       system("/bin/date"); 
      } 
      i+=sizeof(struct inotify_event)+event->len; 
     } 
    } 
} 

Приведенный выше код выполняет команду $ DATE каждый раз, когда файл добавляется в/TMP/TEMP. Измените его в соответствии с вашими потребностями.

+0

, но я не хочу выходить из цикла. Я использую inotify ... монитор floder есть падение в нем. так что в то время как требуется –

+0

что такое i и len? thx –

+0

@justAngela Это урезанная версия вашего кода. 2 цикла. Условие if - это часть (в IN_OPEN), в которой вы используете вызов system(). –

1

Что делает ваша системная команда? Открывает ли файл, который вы меняете? Если это так, разве это не приведет к тому, что ваш код снова запустится и поместит вас в бесконечный цикл (что, по-видимому, вы видите)?

Редактировать - есть an article in Linux Journal, который делает что-то очень похожее на вас. Я заметил, что они используют большой буфер, и комментарии упоминают что-то о выравнивании структуры, поэтому возможно, что вы получаете плохую длину события, которая вызывает переполнение буфера и принуждение вашего кода к циклу дольше, чем ожидалось.

Эфирный способ, я бы проверил (с бит логики отладки printf), что вы зацикливаете, как ожидалось.

Смежные вопросы