0

See original Q&A about grep not accepting netcat output on stderr at a prior StackExchange post.

Concise answer. I like it. Why does adding a tee on the end fail to produce any output?

nc -zvv localhost 3100-3200 2>&1 | grep succeeded | tee test.txt

Using only tee works. Using only grep works. Chaining tee after grep gives no output (console or file).

Any ideas?

Brian
  • 39
  • I could not recreate your result on my system. "It works for me fine" :( Please consider adding some more details. Maybe it is system specific? My version of software answers with "open" localhost [127.0.0.1] 22 (ssh) open localhost [127.0.0.1] 21 (ftp) : Connection refused, and you seems to expect "succeeded" – DevilaN Apr 10 '20 at 07:01
  • @DevilaN When a connection is established, grep will not output anything until 1) its output buffer is full, or 2) nc terminates. The issue is with buffering, and you can turn this off by using grep --line-buffered (with grep implementations that support this non-standard option). The buffering is there for performance reasons, and happens when the output of grep is not a terminal (it's a pipe in the example in the question). – Kusalananda Apr 10 '20 at 07:17
  • @Kusalananda: Yes, but nc is running with example command from OP in under 1 second, so I thought that waiting for buffer is no issue in this case. – DevilaN Apr 10 '20 at 07:21
  • @DevilaN Do you know what service the nc is connecting to when the user in the question is using that command? I.e. what's running on the specified ports? We can assume that it is not responding with Connection refused, because the user says that there is no output. – Kusalananda Apr 10 '20 at 07:24
  • @Kusalananda: I thought that nc -zvv is not waiting for any service output but only connects to find out whether there is port open. To think of now, there might be some app, that is not doing accept() right away and this might be a reason for long scan, but this seems to be very unusual situation (but not impossible). – DevilaN Apr 10 '20 at 07:32
  • @DevilaN So it is. My apologies. I was too quick to react to the pipe from grep at the end. I have reopened the question. The answer is probably that there simply isn't anything listening to the ports in the given range, or that my initial closeing as a dupe was correct because they aren't showing the actual command that they used. – Kusalananda Apr 10 '20 at 07:55
  • if this indeed a buffering issue the OP could use unbuffer (usually from the package 'expect') in order to disable buffering for this command sequence. – noAnton Apr 10 '20 at 11:49

1 Answers1

0

DevilaN, Kusalananda,

Thank you. It was a combination of my impatience and grep and nc behavior. Using the command below on my Raspberry Pi,

nc -nvw1 127.0.0.1 1-65535 2>&1 | grep succeeded | tee test.txt

All the ports were scanned, ~then~ the console printed out 6 open ports. When I used the --line-buffered option, the command behaved as I expected (printing as they were found).

Also, the buffering behavior of grep apparently happens only when piped into tee. When tee is not used and the --line-buffered is not used, grep still prints out the open ports as found.

Without the -w1 option, the first open port is printed on the console by grep, but then the output hangs - actually it's the output of nc that hangs in this case.

Brian
  • 39
  • 1
    grep buffers as soon as its output is not written to a terminal. The fact that it is tee after the pipe is irrelevant, it's the fact that the output is piped that matters. – Kusalananda Apr 11 '20 at 23:44