мониторинг и поиск файла с помощью inotify и инструментов командной строки - PullRequest
0 голосов
/ 19 апреля 2020

Файлы журналов записываются построчно подводными дронами на сервере. Когда на поверхности беспилотники разговаривают с сервером медленно (скажем, ~ 200o / s по телефонной линии, которая не стабильна) и только время от времени (скажем, каждые ~ 6 часов). В зависимости от сообщений, я должен выполнять команды на сервере, когда дроны подключены к сети и когда они вешают другие команды. Другие процессы могут просматривать те же файлы с аналогичными задачами.

На этом сайте можно найти много информации о некоторых похожих проблемах, но решение, на котором я основывался, все еще неудовлетворительно. В настоящее время я делаю это с bash

while logfile_drone=`inotifywait -e create --format '%f' log_directory`; do

    logfile=log_directory/${logfile_drone}

    while action=`inotifywait -q -t 120 -e modify  -e close --format '%e' ${logfile} ` ; do

        exidCode=$?
        lastLine=$( tail -n2  ${logFile} | head -n1 ) # because with tail -n1 I can got only part of the line. this happens quite often
        match =$( # match set to true if lastLine matches some pattern )

        if [[ $action == 'MODIFY' ]] && $match ; then # do something ; fi

        if [[ $( echo $action | cut -c1-5 ) == 'CLOSE' ]] ; then 
            # do something
            break
        fi  

        if [[ $exitCode -eq 2 ]] ; then break ; fi  

    done

    # do something after the drone has hang up

done # wait for a new call from the same or another drone

Основные проблемы:

  1. второе inotify пропускает строки, возможно, из-за других процессов, которые ищут в тот же файл.

  2. способ, которым я ловлю время, похоже, не работает.

  3. Я не могу контролировать 2 дронов одновременно.

В основном код работает более или менее, но не очень надежен. Интересно, можно ли решить проблему 3, поставив вторую функцию l oop, которая вызывается в фоновом режиме при вызове. Наконец, мне интересно, если бы язык более высокого уровня (я знаком с php, который имеет расширение PECL для inotify) не сделал бы это намного лучше. Однако я полагаю, что php не решит проблему 3 лучше, чем bash.

Вот код, где я сталкиваюсь с проблемой внезапного выхода из while l oop, реализованной в соответствии с Philippe's ответом, которая отлично работает в противном случае:

    while read -r action ; do
        ...
        resume=$( grep -e 'RESUMING MISSION' <<< $lastLine )
        if [ -n "$resume" ] ; then
            ssh user@another_server "/usr/bin/php /path_to_matlab_command/matlabCmd.php --drone=${vehicle}" &
        fi

        if [  $( echo $action | cut -c1-5 ) == 'CLOSE' ] ; then ... ; sigKill=true ; fi
        ...
        if $sigKill ; then break; fi

    done < <(inotifywait -q -m -e modify  -e close_write   --format '%e' ${logFile})

Когда я комментирую строку с помощью s sh, сценарий может корректно завершиться с прерыванием, вызванным CLOSE, в противном случае while loop заканчивается преждевременно после команды s sh. S sh помещен в фоновом режиме, потому что код Matlab работает в течение длительного времени.

1 Ответ

0 голосов
/ 19 апреля 2020

monitor mode (-m) из inotifywait может служить лучше здесь:

inotifywait -m -q -e create -e modify -e close log_directory |\
while read -r dir action file; do
    ...
done

monitor mode (-m) не буферизует, он просто выводит все события на стандартный вывод.

Для сохранения переменных :

while read -r dir action file; do
    echo $dir $action $file
done < <(inotifywait -m -q -e create -e modify -e close log_directory)

echo "End of script"
...