简体   繁体   English

在shell脚本中摆脱tail -f

[英]Getting out of tail -f in shell script

I cant seem to make this work. 我似乎无法使这项工作。 This is the script. 这是脚本。

tail -fn0 nohup.out | while read line; do

    if [[ "${line}" =~ ".*ERIKA.*" ]]; then

        echo "match found"
        break

    fi

done

echo "Search done"

The code echo "Search done" does not run even after a match has been found. 即使找到匹配项,代码回显“搜索完成”也不会运行。 I just want the rest of the code to be ran when a match has been found. 我只希望在找到匹配项后运行其余代码。 I have not made it possible yet. 我还没有实现。

Sorry, I am new with log monitoring. 抱歉,我是日志监视的新手。 Is there any workaround with this? 有什么解决方法吗?

I am gonna run the script via Jenkins so, the code should be free flowing and should not require any user interaction. 我将通过Jenkins运行脚本,因此,代码应该可以自由流动并且不需要任何用户交互。

Please help, thanks. 请帮忙,谢谢。

You've got a couple of issues here: 您在这里遇到了几个问题:

  1. tail is going to keep running until it fails to write to its output pipeline, and thus your pipeline won't complete until tail exits. tail会一直运行,直到无法写入其输出管道为止,这样,直到tail退出,管道才会完成。 It won't do that until after your script exits, AND another line (or possibly 4K if buffering, see below) is written to the log file, causing it to attempt to write to its output pipe. 直到脚本退出并且将另一行(如果缓冲,可能是4K,请参见下文)之后,它才会执行该操作,将其写入日志文件,从而使其尝试写入其输出管道。 (re buffering: Most programs are switched to 4K buffering when writing through pipes. Unless tail explicitly sets its buffering, this would affect the above behaviour). (重新缓冲:通过管道写入时,大多数程序会切换到4K缓冲。除非tail显式设置其缓冲,否则会影响上述行为)。

  2. your regex: "${line}" =~ ".*ERIKA.*" does not match for me. 您的正则表达式: "${line}" =~ ".*ERIKA.*"与我不匹配。 However, "${line}" =~ "ERIKA" does match. 但是, "${line}" =~ "ERIKA"确实匹配。

You can use tail's --pid option as a solution to the first issue. 您可以使用tail的--pid选项作为第一个问题的解决方案。 Here's an example, reworking your script to use that option: 这是一个示例,重新编写脚本以使用该选项:

while read line; do
    if [[ "${line}" =~ "ERIKA" ]]; then
        echo "match found"
        break
    fi
done < <(tail --pid=$$ -f /tmp/out)

echo "Search done"

Glenn Jackman's pkill solution is another approach to terminating the tail. 格伦·杰克曼(Glenn Jackman)的杀死方法是另一种终止尾巴的方法。

Perhaps consider doing this in something other than bash: perl has a nice File::Tail module that implements the tail behaviour. 也许考虑用bash以外的方式进行此操作:perl有一个不错的File :: Tail模块,该模块实现了尾部行为。

There are many more questions related to this problem, you may find something you prefer in their answers: 与这个问题有关的问题还有很多,您可能会在他们的答案中找到自己喜欢的东西:

Here's one way, doesn't feel very elegant though. 这是一种方法,不过感觉并不优雅。

tail -fn0 nohup.out |
while IFS= read -r line; do
    if [[ $line == *ERIKA* ]]; then
        echo "match found"
        pkill -P $$ tail
    fi
done

echo "Search done"

您可以使用awk退出:

tail -fn0 nohup.out | awk '/ERIKA/{print "match found ", $0; exit}'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM