检测到字符串后退出尾巴

时间:2018-10-15 09:11:01

标签: bash pipe sh tail process-substitution

我正在写一个障碍,阻止它停止执行脚本,直到记录了某个关键字为止。该脚本非常简单:

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 <后立即退出/ em>?

1 个答案:

答案 0 :(得分:2)

中,当执行以下格式的命令时

command1 | command2

并且command2死亡或终止,接收command1的{​​{1}}的管道断开。但是,这不会立即终止/dev/stdout

因此要实现您想要的,是使用流程替换而不是管道

command1

使用时,实际上可以更详细地看到该行为:

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

$ touch logfile $ tail -f logfile | awk '/STOP/{exit}1;END{print "end"}' 程序将检查是否看到“ STOP”,如果没有,则再次打印该行。如果看到“停止”,它将打印“结束”

当您在另一个终端中做

awk

您看到打印以下输出:

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

此外,如果您仔细观察,会发现至此已经终止。

a # result of print end # awk test STOP, exits and executes END statement ,然后发送“ STOP”:

ps

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"} 发送“ STOP”后:

ps

因此awk程序终止了,但是13625 pts/39 SN 0:00 | \_ bash 32151 pts/39 SN+ 0:00 | \_ tail -f foo 并未崩溃,因为它尚未意识到管道已断开,因为它没有尝试写入它。

在终端中使用管道进行以下操作时,您会看到tail的退出状态:

tail

其中指出$ echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}" $ 141 0 终止的很好,但是awk终止的退出代码为141,表示tail