How can I pipe commands to a netcat that will stay alive?

33

11

echo command | netcat host port

This results in the command being sent to the remote host and some data being read back. But after a few seconds, the connection closes. The -w parameter did not change anything. I am using netcat v1.10 on SuSE 10.1.

Chris

Posted 2011-03-24T17:06:10.383

Reputation: 461

Are you sure it is not the remote host that closes the connection? – user1686 – 2011-03-24T17:18:16.053

Yes. Doing netcat and then manually typing the command results in netcat staying alive indefinitely. – Chris – 2011-03-24T17:40:50.167

Why would it stay alive? it just print the echo parameters and then die? – M'vy – 2011-03-24T17:41:32.787

1I want it to stay alive so that it continues to receive the data coming from the remote server. – Chris – 2011-03-24T18:01:07.060

If you do it the way you wrote it, you just send to the remote server. If you want to receive something, you need to open a listening netcat on the local. – M'vy – 2011-03-24T18:15:53.083

2That's not true. "netcat <host> <port>" opens a bidirectional TCP socket. – Chris – 2011-03-24T18:41:39.723

Answers

34

This works with the nc command on OS X (assuming the command that you want to send is in a file):

cat file - | nc host port

(Essentially, cat dumps the contents of file on stdout and then waits for you on stdin).

By extension, if you want to send the command from the shell itself, you could do this:

cat <(echo command) - | nc host port

Chaitanya Gupta

Posted 2011-03-24T17:06:10.383

Reputation: 601

It's nice as it works on a very bare bones embedded system, where netcat lacks about all the fancy options. – SF. – 2016-11-03T16:02:30.283

{ echo command; cat;} would do the same, and might be considered to be easier to understand. – G-Man Says 'Reinstate Monica' – 2017-12-07T01:59:04.097

1

As I see it the netcat command will hold the socket open until it sees end of input. All these examples demonstrate this without actually saying much about why. I am interacting with SocketTest server using netcat for an extended period just using: cat - | nc localhost 8063. SocketTest is a handy tool that can listen or serve on any TCP or UDP port.

– will – 2018-01-04T03:05:25.270

cat <(echo command) <(sleep 1) | nc host port causes stdin to stay open as long as the sleep command runs without the need to set nc timeouts or have the user enter additional characters. – romanows – 2020-01-19T21:33:12.530

14

With nc on Ubuntu:

nc -q -1 host port

From the Ubuntu nc man page:

 -q seconds
         after EOF on stdin, wait the specified number of seconds and then quit. If seconds is negative, wait forever.

Note that the available nc options vary a lot between distributions, so this might not work on yours (OpenSUSE).

Suzanne Dupéron

Posted 2011-03-24T17:06:10.383

Reputation: 407

13

I found it:

echo command | netcat host port -

My coworker knew it. I don't see that in the documentation at all.

Chris

Posted 2011-03-24T17:06:10.383

Reputation: 461

3

Might it be that the connection is closed at the other end of the socket?

By default, nc closes the connection after completion, if you don't explicitly tell him to stay listening (with the -k option):

 -k    Forces nc to stay listening for another connection after its current
       connection is completed.  It is an error to use this option without the
       -l option.

See man nc.1.


I am successfully streaming data between two machines like this:

  • sender:

    while (true); do 
      echo -n "$RANDOM " | nc <host> <port>
    done
    
  • receiver:

    nc -kl <port> 
    

Campa

Posted 2011-03-24T17:06:10.383

Reputation: 225

2

I don't think you're going to manage this with either netcat or socat. I have just done extensive tinkering with both, and socat looked the most promising.

I managed to set socat up to connect to the remote TCP port and listen on a local unix domain socket (in theory so the link could be kept up all the time) but as soon as the local process detatched from the unix socket (another socat linking the unix socket to stdin/out) it closed the TCP socat session.

The problem here is that each connection through netcat / socat makes a new TCP stream connection to the server, and it closes that TCP stream session when the local end disconnects.

I think you're probably going to have to write some custom proxy software for this that opens the TCP connection to the remote end and then listens locally on a socket / pipe / fifo or whatever and then just sends the data down the existing TCP pipe and returns the results.

Majenko

Posted 2011-03-24T17:06:10.383

Reputation: 29 007

Listen to the all-mighty Matt Jenkins :D – M'vy – 2011-03-24T18:17:26.360

1

Georges' method works well from an interactive shell, but won't help with scripting, when you're e.g. calling your script as nohup ./script &.

I found replacing stdin with a dummy fifo helps.

 mkfifo dummy
 cat command.txt dummy | nc host port

Since nothing ever writes to the fifo, after outputting the file, cat hangs on it indefinitely.

SF.

Posted 2011-03-24T17:06:10.383

Reputation: 154

0

socat's shut-none option should help here:

Changes the (address dependent) method of shutting down the write part of a connection to not do anything.

You'll probably also need to override the default timeout period using -t <timeout>, otherwise the socket will be closed after 0.5s. This option overrides the default behaviour, which is:

When one of the streams effectively reaches EOF, the closing phase begins. Socat transfers the EOF condition to the other stream, i.e. tries to shutdown only its write stream, giving it a chance to terminate gracefully. For a defined time socat continues to transfer data in the other direction, but then closes all remaining channels and terminates.

So, a command such as:

echo 'blah' | socat -t 10 stdio tcp:<addr>:<port>,shut-none

will keep the socket open for 10s after sending the 'blah'.

Jeremy

Posted 2011-03-24T17:06:10.383

Reputation: 101

0

Your command terminates, if either the remote host closes the connection (or isn't reachable) or the command before the pipe is terminated (while netcat still sends the rest of its input queue).

allo

Posted 2011-03-24T17:06:10.383

Reputation: 731