SH / BASH - сканировать файл журнала до появления текста, затем выйти. Как? - PullRequest
0 голосов
/ 06 апреля 2010

Редактировать - 7 апреля немного переформулировал вопрос, чтобы прояснить его.

Текущая рабочая среда - OSX 10.4.11.

Я хочу отсканировать файл журнала для определенной фразы. Файл журнала НЕ может быть очищен в начале скрипта. Таким образом, скрипт должен сканировать только изменения в журнале.

Мой текущий скрипт:

#!/bin/sh
  tail -f log.txt | while read line 
do
  if echo $line | grep -q 'LOL CANDY'; then
    echo 'LOL MATCH FOUND'
    exit 0
  fi
done

Он работает должным образом в том смысле, что он будет «LOL MATCH FOUND» сразу же после поиска «LOL CANDY», но на самом деле он не выйдет из сценария, пока не появится какое-то другое дополнение к журналу ПОСЛЕ «LOL CANDY». Мне нужно, чтобы немедленно выйти. И хотя я не уверен, что это определенно связано, существует проблема того, что "tail -f" остается открытым навсегда. Может кто-нибудь дать мне пример, который будет работать без использования tail -f?

Если хотите, можете дать мне скрипт bash, поскольку OSX может обрабатывать sh, bash и некоторые другие оболочки, я думаю.

Ответы [ 6 ]

2 голосов
/ 07 апреля 2010

Вы очищаете log.txt при втором запуске скрипта? Возможно, вы интерпретируете, что это требует двух появлений вашей строки выхода, когда на самом деле это только один. Поскольку вы используете -f, он будет перечислять все добавленное только после запуска вашего скрипта.

Итак, когда вы первый раз поймаете его, вы получите желаемую линию и уйдете. Вы перезапустите скрипт, он будет игнорировать первый экземпляр, потому что он не будет введен в ваш аргумент -f для tail. Однако следующий случай должен выйти. Если вы загляните в свой журнал, вы увидите две строки LOL CANDY, потому что вы просто следуете за хвостом и не смотрите на то, что уже есть в журнале.

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

 #!/bin/sh
  if grep 'LOL CANDY' log.txt; then
   echo 'LOL MATCH FOUND'
   exit 0
  fi

  tail -f log.txt | while read line 
do
  if echo $line | grep -q 'LOL CANDY'; then
    echo 'LOL MATCH FOUND'
    exit 0
  fi
done

Также, если вы хотите избавиться от хвоста -f, вы можете делать то, что я перечислил в первом случае, в бесконечном цикле while (синтаксис может быть неправильным, давно):

#!/bin/sh
while (1)
do
  if grep 'LOL CANDY' log.txt; then
   echo 'LOL MATCH FOUND'
   exit 0
  fi
done

Конечно, если ваш лог-файл становится достаточно большим, это потребует много ресурсов и займет много времени.

1 голос
/ 27 апреля 2012

Может быть, этот скрипт поможет вам:

#!/bin/bash

FILE=/tmp/mytest
PIPE=/tmp/myfifo

if [[ ! -p $PIPE ]];
then
        mkfifo $PIPE
fi

tail -n 0 -f $FILE >> $PIPE &
TAILPID=$!

while read line < $PIPE
do
        echo "Received: $line"
        if [ "x$(echo "$line" | grep -l -P "asdf")" != "x" ];
        then
                echo "MATCHES"
                kill -TERM $TAILPID
        fi
done;
0 голосов
/ 21 февраля 2015

Я искал это и выяснил следующие работы (для моего приложения в любом случае):

tail -n 1 -f /var/log/vmkernel.log | grep -m 1 IOMMUIntel >>/var/log/vmkernel.log

Завершает журнал, grep находит текст и grep записывает текств журнал, который убивает tail, и я вернулся к приглашению.

В частности, он проверяет, активируется ли пропущенная видеокарта при загрузке виртуальной машины на VMware ESXi.

Полный проект здесь .

0 голосов
/ 07 апреля 2010

Я не совсем уверен, понимаю ли я ваш вопрос. Во всяком случае, я попробовал ваш скрипт, он не вышел при первом запуске. Итак, как насчет добавления:

pid=`ps -ef | grep "tail -f log.txt" | grep -v grep | awk '{print $2}'`
kill -2 $pid

до exit 0 так что tail -f выходит?

0 голосов
/ 07 апреля 2010

попробуйте

(tail -f  file| awk '/interesting/{print;exit}')
0 голосов
/ 07 апреля 2010
tail -f log.txt | sed -n '/interesting/{
p
q
}'

В основном читайте строки, ничего не печатая; когда вы увидите что-то интересное, напечатайте строку и выйдите.

О, я вижу, ты не хочешь "хвост -f"; это странно, он должен выйти, когда в следующий раз необходимо записать в канал. Если он никогда не запишет в канал снова, это может быть проблемой.

Полагаю, вы могли бы сделать:

tail -f log.txt | sed -n '/interesting/{
p
q
}'
echo "EOF" >> log.txt

Это дает ему что-то для эха, поэтому он пытается и терпит неудачу и завершается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...