В bash , при выполнении команды вида
command1 | command2
и command2
умирает или завершается, канал, по которому получает command1
, его /dev/stdout
разрывается,Однако это не прекращается command1
мгновенно.
Таким образом, для достижения того, что вы хотите, нужно использовать подстановка процесса , а не канал
awk '/STOP/{exit}1' < <(tail -f logfile)
Когда вы используете awk , вы на самом деле можете увидеть поведение более подробно:
$ 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
Вы видите, что awk выводит следующий вывод:
a # result of print
end # awk test STOP, exits and executes END statement
Кроме того, если вы посмотрите более внимательно, вы увидите, что awk на этом этапе уже завершено.
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
.