bash - grep 从超慢连续流式日志中找到,一旦找到没有缓冲区的字符串就退出

标签 bash unix kubernetes buffer stdout

更新:

随着@Tanktalus 的回答,我意识到它是最左边的 kubectl命令被缓冲。

# will hang forever, because RHS pipe is broken, and LHS pipe need to send 
# the output to the pipe to realize the broken pipe, but as the buffer is 
# never filled, it's never broken
kubectl logs -f pod -n NAMESPACE | grep -q "Indicator"  

# put LHS to the background, because I don't care if it hang, I just need the log.
(kubectl logs -f pod -n NAMESPACE &) | grep -q "Indicator"  


但我有一个新问题,以下现在永远挂起:(kubectl logs -f pod -n NAMESPACE &)| tee log >(grep -q "Indicator")
原始问题:
首先,其他类似问题不再重复,我已全部阅读。细微的区别是,我的流式日志在我尝试 grep 的字符串指示符之后立即处于非事件状态。

我有来自 kubernetes pod 的连续流式日志输出。指标字符串“Indicator”将出现在日志生成器应用程序的末尾,日志生成器变为sleep infinity .所以日志仍然会被流式传输,但不会提供新的输出。

我正在尝试使用管道 |重定向我的 kubernetes 的流式日志,然后 grep 日志的每一行,直到找到“指示器”,然后我想(立即)退出。我尝试过的命令如下:
# none of them worked, they all show the Indicator line, and then hangs forever.
kubectl logs -f pod -n NAMESPACE | tee test.log >(grep -q "Indicator")  
stdbuf -o 0 kubectl logs -f pod -n NAMESPACE | tee test.log >(grep -m1 "Indicator")
stdbuf -o 0 kubectl logs -f pod -n NAMESPACE | tee test.log >(grep -q --line-buffered "Indicator")
stdbuf -o 0 kubectl logs -f pod -n NAMESPACE | grep -q --line-buffered "Indicator"

但是因为在“Indicator”之后,只会多出一行日志“+ Sleep infinity”。我猜管道最左端的输出缓冲区没有满,因此它没有传递给 grep?

有没有办法解决这个问题?

最佳答案

我怀疑是因为kubectl没有退出,shell 没有继续。如果您查看 ps输出,你会注意到 grep -m1 ...实际上确实退出了,并且不再存在,但管道的其余部分仍然存在。

所以我怀疑你需要颠倒这个。例如,在 perl 中,我会使用 open打开到 kubectl 的管道,读取输出,直到找到我想要的,杀死 child ,然后退出。在 C 中,与 popen 相同。 .我不确定 bash 是否提供了相当程度的控制。

例如:

 perl -E 'my $pid = open my $fh, "-|", qw(perl -E), q($|++; say for 1..10; say "BOOM"; say "Sleep Infinity"; sleep 50) or die "Cannot run: $!"; while(<$fh>) { if (/BOOM/) { say; kill "INT", $pid; exit 0 } }'

您必须替换 open 中的内容在 "-|" 之后使用您自己的命令和 if (/BOOM/)使用您自己的正则表达式,否则它应该可以工作。

关于bash - grep 从超慢连续流式日志中找到,一旦找到没有缓冲区的字符串就退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54356952/

相关文章:

linux - Echo -e 在我的脚本中不起作用

linux - 我如何阻止某人使用 linux 中的 write 命令向我的控制台发送垃圾邮件

C + UNIX,siglongjmp 和 sigsetjmp

networking - 使用 EKS 与 IP 白名单服务通信

kubernetes - 在一台或两台本地物理 Ubuntu 服务器上使用 helm 和带有 Microk8s 的 Kubernetes 集群

linux - 将多个shell脚本集成到一个脚本中

linux - 字符串替换中的 bash 变量

bash - 使用 xargs 调用 shell 函数

c - 替代 lseek 来跟踪文件 (Posix)

mysql - 将 kubernetes 上托管的 jenkins 连接到 Google Cloud Platform 上的 MySQL