<p><strong>UPDATE:</strong></p>

<p>With @Tanktalus 's answer, I realized that it was the left most <code>kubectl</code> command is buffered. </p>

<pre class="lang-sh prettyprint-override"><code># 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 &amp;) | grep -q "Indicator"  

</code></pre>

<p>But I have a new problem, the following now hang forever:<br>
<code>(kubectl logs -f pod -n NAMESPACE &amp;)| tee log &gt;(grep -q "Indicator")</code></p>

<hr>

<p><strong>ORIGINAL QUESTION:</strong><br>
First of all this is not repeated with other similar questions, I have read them all. The subtle difference is that my streamed log is inactive right after the string indicator I am trying to grep.</p>

<p>I have a continuous streamed log output from kubernetes pod. The indicator string "Indicator" will appear in the end of the log generator application, and the log generator goes <code>sleep infinity</code>. So the log will still be streamed, but gives no new output.</p>

<p>I am trying use a pipe <code>|</code> to redirect my kubernetes' streamed log, then grep each line of the log, until I find the "Indicator", then I want to (immediately) exit. The commands I have tried are like:</p>

<pre><code># none of them worked, they all show the Indicator line, and then hangs forever.
kubectl logs -f pod -n NAMESPACE | tee test.log &gt;(grep -q "Indicator")  
stdbuf -o 0 kubectl logs -f pod -n NAMESPACE | tee test.log &gt;(grep -m1 "Indicator")
stdbuf -o 0 kubectl logs -f pod -n NAMESPACE | tee test.log &gt;(grep -q --line-buffered "Indicator")
stdbuf -o 0 kubectl logs -f pod -n NAMESPACE | grep -q --line-buffered "Indicator"
</code></pre>

<p>But because after the "Indicator", there will be only one more line of log "+ Sleep infinity". I guess the output buffer from the leftmost end of the pipe is not full, and thus it's not passed to grep?</p>

<p>Is there any way to solve this issue ?</p>

Psyduck
<p>I suspect it's because <code>kubectl</code> hasn't exited that the shell doesn't continue on. If you look at the <code>ps</code> output, you'll notice that <code>grep -m1 ...</code> does actually exit, and doesn't exist anymore, but the rest of the pipe still exists.</p>

<p>So I suspect you'll need to invert this. In perl, for example, I would use <code>open</code> to open a pipe to kubectl, read the output until I found what I wanted, kill the child, and exit.  In C, the same thing with <code>popen</code>. I'm not sure if bash gives quite that level of control.</p>

<p>For example:</p>

<pre><code> 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(&lt;$fh&gt;) { if (/BOOM/) { say; kill "INT", $pid; exit 0 } }'
</code></pre>

<p>You'll have to replace the stuff in the <code>open</code> after <code>"-|"</code> with your own command, and the <code>if (/BOOM/)</code> with your own regex, but otherwise it should work.</p>
