9

I'm trying to send commands to a tcp port using netcat and pipe response
when I run netcat and type my command it prints response correctly but when I pass command from a pipe it sends the command correctly but doesn't print response

So, this works correctly:

netcat  localhost 9009

while this just sends command but doesn't print response:

echo 'my_command' | netcat  localhost 9009

why?
How can I make netcat to print response text ?

  • this is probably happening to you – Jeff Schaller Jun 13 '16 at 2:10
  • @JeffSchaller: no! unfortunately using those commands doesn't help! this time it blocks forever! – RYN Jun 13 '16 at 2:26
  • Which netcat are you using? Unfortunately there's a dozen different variations of the netcat tool, and they don't all behave the same. Also, what is on the remote end? – Patrick Jun 13 '16 at 2:33
  • @Patrick: my netcat is OpenBSD netcat (Debian patchlevel 1.105-7ubuntu1) version; and at the remote end is telegram-cli on the same machine. – RYN Jun 13 '16 at 2:46
  • I think I found a man page for that netcat, but I don't see any flags which would control what I suspect is happening. I suspect that once netcat receives the EOF on STDIN, that it immediately shuts down both sides of the socket instead of doing a half-close and waiting for the remote side to close its end. If socat is an option, I would highly recommend it instead. There's only one socat, so you don't have the portability issues with there being a dozen different flavors of it, it behaves a lot more sanely, and is highly configurable. – Patrick Jun 13 '16 at 3:34
6

As @Patrick said, this problem is usually due to netcat exiting before the response has been given. You remedy that by adding -q 2 to the command line, i.e., tell netcat to hang around 2 seconds after detecting EOF on standard input. Obviously you can make it wait some other number of seconds as well.

  • Thanks; -q 2 worked but is it trust-able? it is making web request I can't be sure 2s is always enough! can I ? – RYN Jun 14 '16 at 1:13
  • 1
    Use a larger number to make it wait longer, or some negative number to make it wait indefinitely. There's also the -w option to play with. This is all in the man nc page of course. – Ralph Rönnquist Jun 14 '16 at 6:15
  • 3
    it says invalid option -- 'q' – Blauhirn Sep 12 '18 at 19:21
6

Use this:

cat <(echo command) - | nc host port

The problem is that nc will close the connection immediately after stdin is closed, which is very quick for a simple my_command string, and thus never gets the chance to receive a response. (If you pipe a very large file you will see that it might get a response before it's done sending the file).

Enter cat with - as second argument: It makes cat listen on stdin for more content to pipe through after it has sent the contents of the first argument. The first argument is just getting the echo command through cat – it could also be a file with your commands a la cat < file - | ....

Alternatively do this:

(echo command; while true; do sleep 0.01; echo -n "#"; done) | nc host port

This sends unlimited # characters on the 2nd line of the input. Using # works for a bash like remote that would ignore this as a comment. I chose a small wait time of 10 milliseconds here, so it reacts faster on connection end. YMMV.

The downside of that can be that cat or the while loop and nc keep running until you hit ^C or ^D on the shell. It really depends on the remote end.

Adding a timeout using -w 1 (OSX netcat) or -i 1 (nmap's ncat) makes it close the connection and nc after 1 second, but cat will keep running until you enter some character and the pipe breaks (I think).

However, it works if the remote side will automatically close the connection after receiving and handling the command - this will also end the nc client and the process piping into it.

This answer is based on this this answer to an identical superuser question.

  • { echo my_command; cat;} would do the same and might be considered to be easier to understand. – G-Man Dec 7 '17 at 1:58
1

Different openbsd-netcat versions are quirky, needing different combinations of -w <seconds>, -q <seconds>, -N and even need different arguments depending on what is running on the other end of the connection. Using timeout options with certain versions or servers cause delays, and not using them might result in an extremely long (infinite?) delay. And I would expect different quirks with gnu netcat, but don't know if they are different between versions of it.

For example version 1.130_3 from archlinux takes extremely long (forever?) when I do this:

$ echo response | nc -l 9999 &
[1] 15190

$ time echo request | nc localhost 9999
request
response

(wait forever possibly)

But it works with -N added to either the server or the client.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.