Выход из хвоста при обнаружении струны - PullRequest
0 голосов
/ 15 октября 2018

Я пишу барьер, чтобы остановить выполнение сценария до тех пор, пока не будет зарегистрировано определенное ключевое слово.Сценарий довольно прост:

tail -F -n0 logfile.log | while read LINE; do
    [[ "$LINE" == *'STOP'* ]] && echo ${LINE} && break;
done

или

tail -F -n0 logfile.log | grep -m1 STOP

Тем не менее, несмотря на вывод STOP , как только он обнаружен, эти куски кода завершаются только после следующей строки пишется .Т.е.:

printf "foo\n" >> logfile.log  # keeps reading
printf "foo\n" >> logfile.log  # keeps reading
printf "STOP\n" >> logfile.log # STOP printed
printf "foo\n" >> logfile.log  # code exits at last

К сожалению, я не гарантирую, что после STOP будет зарегистрирована другая строка кода (не в течение интервала, полезного для моих целей).

Обходной путь, найденный до сих пор, tail также еще один файл, который я точно знаю, обновляется довольно часто, но что такое «чистое» решение, чтобы код завершал работу сразу после регистрации STOP ?

1 Ответ

0 голосов
/ 15 октября 2018

В , при выполнении команды вида

command1 | command2

и command2 умирает или завершается, канал, по которому получает command1, его /dev/stdout разрывается,Однако это не прекращается command1 мгновенно.

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

awk '/STOP/{exit}1' < <(tail -f logfile)

Когда вы используете , вы на самом деле можете увидеть поведение более подробно:

$ touch logfile
$ tail -f logfile | awk '/STOP/{exit}1;END{print "end"}'

Эта awk программа проверит, виден ли "STOP", и если нетснова напечатайте строку.Если «STOP» виден, он напечатает «end»

Когда вы делаете в другом терминале

$ echo "a" >> logfile
$ echo "STOP >> logfile
$ echo "b" >> logfile

Вы видите, что выводит следующий вывод:

a             # result of print
end           # awk test STOP, exits and executes END statement

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

ps перед отправкой "STOP":

13625 pts/39   SN     0:00  |        \_ bash
32151 pts/39   SN+    0:00  |            \_ tail -f foo
32152 pts/39   SN+    0:00  |            \_ awk 1;/STOP/{exit}1;END{print "end"}

ps после отправки "STOP":

13625 pts/39   SN     0:00  |        \_ bash
32151 pts/39   SN+    0:00  |            \_ tail -f foo

Таким образом, программа awk завершилась, но tail не произошел сбой, потому чтоон еще не знает, что канал сломан, поскольку он не пытался записать в него.

Когда вы делаете следующее в терминале с конвейером, вы видите состояние выхода tail:

$ echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}"
$ 141 0

В котором говорится, что awk завершено красиво, но tail завершено с кодом выхода 141, что означает SIGPIPE.

...