2

I put this command into bash, expecting it to print FOO and then wait for more input:

(echo FOO; cat) | grep FOO | cat

Instead it prints nothing, and waits until I press Ctrl+D before anything appears.

If I remove the |cat at the end, the issue goes away.

What is going on here? Is grep waiting for more lines, and only when piped to something else? Or is bash/cat waiting?

Tor Klingberg
  • 4,790
  • 6
  • 41
  • 51
  • 1
    both `cat`s are unnecessary. Why would you think it is grep waiting when you have yourself said that the issue goes away when you remove the last cat ? The first cat is the problem, you haven't give it an argument so it is reading from STDIN. –  Apr 27 '15 at 14:15
  • I know, I simplified the issue before posting. Originally the last `cat` was an other grep command, and the `(echo FOO; cat)` was a `tail -f`. I suspect the grep is waiting because it does not seem to matter what I pipe it to, as long as it is piped to something. I also know that a command can tell whether it is piped somewhere or not. For example `grep` can print with colors on the command line, but without if piped somewhere. – Tor Klingberg Apr 27 '15 at 14:19
  • 1
    I don't think the `cat`s can be "unnecessary" in a theroretical question like this. – Michael Jaros Apr 27 '15 at 14:21
  • grep doesn't wait, and piping `tail -f` into two greps would not wait for input unless the grep wasn't matching anything. Post your actual problem instead of this which is clearly caused by cat waiting. –  Apr 27 '15 at 14:22
  • @MichaelJaros How can't they , the command would work without them and won't with them ? –  Apr 27 '15 at 14:23
  • @JID: you're wrong.. I can reproduce the behaviour. check my answer. and regarding your second comment, I can also reproduce that. the second cat does make a difference. – Karoly Horvath Apr 27 '15 at 14:23
  • @JID: I meant: The OP used the `cat`s to provide a minimal example of what they wanted to understand. So they are necessary to reproduce the problem. I agree that they are kind of pointless in production code. – Michael Jaros Apr 27 '15 at 14:28
  • @KarolyHorvath As i have said in the comment on your answer i misunderstood OPs problem and my comments were to address what i thought was the problem. –  Apr 27 '15 at 14:28

1 Answers1

3

The first cat is waiting for input.

grep, for performance reasons, is reading in chunks, there's not enough input, so it just waits. This can be resolved by forcing it to read each line:

(echo FOO; cat) | grep --line-buffered FOO | cat
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
  • 2
    This still waits for more input though,so i am not wrong.Actually i'm going to admit that i misread the question and am completely wrong as Op wanted that behaviour :( –  Apr 27 '15 at 14:25
  • Of course it waits, and it will till stdin is closed. – Karoly Horvath Apr 27 '15 at 14:25
  • Thanks! I think this is the same issue as http://stackoverflow.com/questions/7161821/how-to-grep-a-continuous-stream I also found some info [here](http://blog.jpalardy.com/posts/grep-and-output-buffering/) and [here](http://www.perkin.org.uk/posts/how-to-fix-stdio-buffering.html). – Tor Klingberg Apr 27 '15 at 14:27
  • RIght @JID , it hangs indefinably , just like the original post. – z atef Apr 27 '15 at 14:27
  • 1
    @NullSoulException: and that's exactly what the OP wants. the *issue* was that grep didn't print anything though there was a matching line. – Karoly Horvath Apr 27 '15 at 14:28
  • you are right , @Karoly Horvath ... – z atef Apr 27 '15 at 14:44