从超慢的连续流式日志中获取 grep,并在没有缓冲区的情况下找到字符串后退出
grep from super slow continuous streamed log and exit once string is found without buffer
更新:
根据@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 日志的每一行,直到找到 "Indicator",然后我想(立即)退出.我试过的命令是这样的:
# 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 的管道,读取输出直到找到我想要的,杀死子进程,然后退出。在 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/)
中的内容替换为您自己的正则表达式,否则它应该可以工作。
更新:
根据@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 日志的每一行,直到找到 "Indicator",然后我想(立即)退出.我试过的命令是这样的:
# 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 的管道,读取输出直到找到我想要的,杀死子进程,然后退出。在 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/)
中的内容替换为您自己的正则表达式,否则它应该可以工作。