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
  • 29
  • 1
  • 5
  • 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
  • 29
  • 1
  • 5
  • 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