在shell脚本中退出尾部-f

时间:2014-03-20 15:25:33

标签: linux bash shell unix

我似乎无法完成这项工作。 这是剧本。

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

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

        echo "match found"
        break

    fi

done

echo "Search done"

即使找到匹配项,代码 echo“Search done”也不会运行。 我只是希望在找到匹配项时运行其余代码。 我还没有成功。

抱歉,我是日志监控新手。 这有什么解决方法吗?

我将通过Jenkins运行脚本,所以代码应该是自由流动的 并且不应要求任何用户交互。

请帮助,谢谢。

3 个答案:

答案 0 :(得分:3)

你在这里遇到了几个问题:

  1. tail将继续运行,直到它无法写入其输出管道,因此您的管道不会完成,直到尾部退出。在脚本退出之前它不会这样做,并且另一行(或者如果缓冲可能是4K,见下文)被写入日志文件,导致它尝试写入其输出管道。 (重新缓冲:大多数程序在通过管道写入时切换到4K缓冲。除非尾部明确设置其缓冲,否则会影响上述行为。)

  2. 你的正则表达式:"${line}" =~ ".*ERIKA.*"与我不符。但是,"${line}" =~ "ERIKA"确实匹配。

  3. 您可以使用tail --pid选项作为第一个问题的解决方案。这是一个示例,重新编写脚本以使用该选项:

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

    Glenn Jackman的解决方案是终止尾部的另一种方法。

    也许考虑用bash以外的方法做这件事:perl有一个很好的File::Tail模块来实现尾部行为。

    还有更多与此问题相关的问题,您可以在答案中找到自己喜欢的内容:

答案 1 :(得分:0)

这是一种方式,虽然感觉不是很优雅。

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"

答案 2 :(得分:0)

您可以使用awk退出:

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