inotify проблемы при запуске системы

Я хочу отслеживать папку.

Каждый раз, когда появляется уведомление, я хочу запустить системную командную строку. Проблемы при использовании системной команды. Каждое новое событие появляется 3 раза, хотя должно появляться один раз. РЕДАКТИРОВАТЬ: Спасибо за повторы. Я нашел ошибку. Система выполнила папку, которая находилась внутри отслеживаемого файла. вот почему каждый раз, когда я бросал фодер в отслеживаемую папку, событие печаталось 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;
            }

        }

    }

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

КАК Я МОГУ ЗАСНУТЬ ПОКА(1) НА 1 МИНУТУ? СКОРОСТЬ(60); всплывает inotify void: был открыт вместо папки1: был открыт, когда я бросил файл в отслеживаемой папке

./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

person just ME    schedule 24.01.2012    source источник
comment
В первом блоке if(){} есть разрыв. i не будет увеличиваться после этого блока, а остальное прочитанное будет пропущено. Подсказка: используйте цикл for(;;), который понятнее.   -  person wildplasser    schedule 24.01.2012
comment
я добавил перерыв, потому что мне нужно. но это не работает   -  person just ME    schedule 24.01.2012
comment
@justAngela Но как насчет внешнего цикла while (1). Это приведет к повторному выполнению внутреннего цикла. Смотрите мой ответ.   -  person Abhijeet Rastogi    schedule 24.01.2012
comment
Break выходит только из внутреннего цикла (что не имеет смысла). Вы вызываете эту программу из другой программы, используя system()?   -  person wildplasser    schedule 24.01.2012
comment
inotify должен следить за папкой столько, сколько вы пожелаете. я хочу выполнить другую программу, когда я помещаю файл в отслеживаемую папку. проблема появляется при запуске исполняемого файла. он выполняет его бесконечное количество раз, но я этого не хочу. я просто хочу выполнить его в тот момент, когда я помещаю файл в папку моего монитора.   -  person just ME    schedule 24.01.2012
comment
Пожалуйста, переформулируйте свою проблему. Вполне естественно, что ваша программа работает вечно, так как ее внешний цикл while(1) нельзя разорвать. Также возможно, что вы пропускаете события, потому что вы выходите из внутреннего цикла до того, как buf[] исчерпан (по крайней мере, вы не проверяете его)   -  person wildplasser    schedule 24.01.2012
comment
@wildplasser, но системная команда должна выполняться, когда я помещаю файл в отслеживаемую папку. в моем случае этого не происходит. похоже на то, что inotify видит, что я удаляю файл за файлом. если я прокомментирую system(), все работает нормально (четные числа появляются только в тот момент, когда я помещаю файл в папку)   -  person just ME    schedule 24.01.2012
comment
Возможно, программа или скрипт home/test/userr недоступен или не может быть выполнен пользователем, который запускает inotify-thing. Может быть, вы могли бы проверить возвращаемое значение system() и errno ?   -  person wildplasser    schedule 24.01.2012
comment
системная команда выполняется правильно, потому что она возвращает ожидаемые значения   -  person just ME    schedule 24.01.2012


Ответы (2)


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

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

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

ПО ЗАПРОСУ (рабочий код):

#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. Измените его в соответствии с вашими потребностями.

person Abhijeet Rastogi    schedule 24.01.2012
comment
но я не хочу выходить из цикла. я использую inotify .. он следит за флодером, есть ли в нем падение. так что пока нужно - person just ME; 24.01.2012
comment
@justAngela Это урезанная версия вашего кода. 2 цикла while. Условие if — это часть (в IN_OPEN), где вы используете вызов system(). - person Abhijeet Rastogi; 24.01.2012
comment
Спасибо за повтор. Как это сделать, если я хочу запускать систему каждый раз, когда я помещаю файл в папку монитора/ - person just ME; 24.01.2012
comment
Конечно, приведенный выше код будет выполняться только при первом открытии чего-либо? Так что, если OP удалит еще один файл, они не увидят это второе событие? - person Jon Cage; 24.01.2012
comment
Спасибо за повтор. Мне нужно запускать исполняемый файл каждый раз, когда я помещаю файл в мою отслеживаемую папку. как это сделать? кажется, мой код работает неправильно - person just ME; 24.01.2012
comment
@justAngela, кстати, почитай. meta.stackexchange.com/questions/ 5234/ :) - person Abhijeet Rastogi; 24.01.2012
comment
Как усыпить приложение на 1 минуту? Я пытался поставить set sleep (60), но теперь, когда появляется новое событие, вместо показа, например: folder1: был открыт, он появился недействительным: был открыт - person just ME; 26.01.2012
comment
@justAngela Почему ты отредактировал пост? Это сделало бы все ответы неуместными. Вернитесь назад и для более широкой аудитории снова задайте новый вопрос, если хотите. - person Abhijeet Rastogi; 26.01.2012

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

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

В любом случае, я бы проверил (с небольшим количеством логики отладки printf), что вы выполняете цикл, как и ожидалось.

person Jon Cage    schedule 24.01.2012