`tail -f` 直到看到文本

`tail -f` 直到看到文本

我有一个带有命令行界面的 CI 服务器,它允许我远程启动一项工作(jenkinsCI 服务器和jenkins-cli.jar工具)。

在我开始工作后,我tail -f记录日志(抱歉命令混乱):

ssh -t my-jenkins-host.com "tail -f \"/var/lib/jenkins/jobs/$job_name/builds/\`ls -ltr /var/lib/jenkins/jobs/$job_name/builds/ | grep '^l' | tail -n 1|awk '{print \$9}'\`/log\""

作业成功完成后(通常至少 5 分钟),我会在输出中看到以下行:

Finished: SUCCESS

此时有什么好方法可以停止拖尾日志吗?即有类似tail_until 'some line' my-file.log命令吗?

奖金:如果您可以提供一个答案,当 SUCCESS 匹配时返回 0,当 FAILURE 匹配时返回 1,并且您的解决方案适用于 Mac! (我相信是基于bsd的)

答案1

您可以通过管道传输tail -finto sed,告诉它在看到您正在搜索的行时退出:

tail -f /path/to/file.log | sed '/^Finished: SUCCESS$/ q'

sed默认情况下会输出它处理的每一行,并在看到该行后退出。tail当该进程尝试写入下一行并发现其输出管道已损坏时,该进程将停止

答案2

tail -f my-file.log | grep -qx "Finished: SUCCESS"

-q,意思是安静,一旦找到匹配就退出

-x使grep整条线匹配

对于第二部分,请尝试

tail -f my-file.log | grep -m 1 "^Finished: " | grep -q "SUCCESS$"

-m <number>告诉 grep 在之后停止数字火柴

并且只有在行尾找到grep -q退出状态才会是0SUCCESS

如果你想查看所有输出,你不能使用grep -q,但你仍然可以这样做

tail -f my-file.log | grep -m 1 "^Finished: "

除了将退出状态设置为 1(如果FAILURE出现)之外,它会执行所有操作。

答案3

我不喜欢这里的任何答案,所以决定推出自己的答案。此 bash 脚本满足所有标准,并包含失败时退出 1 的奖励。

#!/bin/bash
while IFS= read -r LOGLINE || [[ -n "$LOGLINE" ]]; do
    printf '%s\n' "$LOGLINE"
    [[ "${LOGLINE}" == "Finished: SUCCESS" ]] && exit 0
    [[ "${LOGLINE}" == "Finished: FAILURE" ]] && exit 1
done < <(timeout 300 tail -f my-file.log)
exit 3

还包括超时功能,这将导致退出代码为 3。如果您的系统上没有超时命令,请从 Anthony Thyssen 获取 timeout.sh 脚本:

https://antofthy.gitlab.io/software/(搜索“超时:”)

根据下面的评论,我更新了日志打印以停止转义字符扩展,并包含标准“读取”的所有功能。看https://stackoverflow.com/a/10929511以获得完整的“阅读”详细信息。此处不需要 EOF 检查,但为了完整性而包含此检查。

答案4

你也试试

 grep -q 'App Started' <(tail -f /var/log/app/app.log)

相关内容