I've been fiddling with getting this to work for a while now, so I suspect some sort of fundamental misunderstanding about how pipes work is the root cause of my troubles.

My goal is to initiate a TCP connection to some remote host via netcat and have two named pipes on the filesystem: one that processes can read from to get incoming data, and other that processes can write to that serve as outgoing data. I am presently using the following construction:

mkfifo in
mkfifo out
cat out | netcat foo.bar.org 4000 > in &

From here, I would like to permit other processes to read and write to/from this open TCP connection. Should this "just work", or is there a reason why a construct like this can't work?

What seems to happen at present is that I can read from out without issue, but when I write to in I get output mentioning a broken pipe and all subsequent communication appears to be dead. Thoughts?

(Related: I originally used:

netcat foo.bar.org 4000 < out > in &

but found it to block waiting for input. I'm curious about this as well, but it's probably better addressed in a separate question.)

3 Answers 3

cat out | netcat foo.bar.org 4000 > in &

I think the problem is that cat will exit as soon as it receives an EOF from the out pipe. And when cat exits, the rest of the pipeline (including netcat) gets terminated as well.

Try something like this instead:

while true; do cat out; done | netcat foo.bar.org 4000 > in &

Thus, cat gets restarted as often as needed, and any EOFs appearing in the out pipe are effectively handled.

  • I tried this, but still receive write(stdout): Broken pipe after (or shortly after) writing to the out pipe.
    – noffle
    Commented Jun 21, 2012 at 16:21

I had faced with this problem too. The main problem is netcat. It is a great tool, but it closes the connection when one of its connected input or output file descriptors are closed. It doesn't do anything when server is not listening and it exits when the other peer is closed. As long as you setup the server correctly and keep your file descriptors open, it will work. For example I tested the following scenario and it worked very well: in a terminal setup an echo server (I set it up like below):

mkfifo loopFF
netcat -t -l -p 4000 <loopFF | tee loopFF

now in another terminal setup your fifo connection to your server:

mkfifo in
mkfifo out
netcat 4000 <out >in &

print out whatever server sends to you (and keep it running, if you use in fifo in an application that closes one end on its termination, netcat closes the connection)

cat in &

and in the same terminal:

cat > out

now whatever you type will be printed again (after hitting Enter). Closing this command will also close the connection.

  • I can see that it's not the case when I try it out myself, but why does netcat -t -l -p 4000 < loopFF | tee loopFF not cause an infinite feedback loop with itself?
    – noffle
    Commented Jun 1, 2012 at 21:18
  • @noffle because, as I said, netcat will close whenever one of its network connections closes. If you close the client (which sends a string and receives the same string), netcat server will be closed too. I wrote a server code for myself in this case that forks itself to handle multiple clients and reconnect of clients.
    – saeedn
    Commented Jun 2, 2012 at 9:19

The analysis of Steven Monday looks good to me: cat returns after your 1st write to out because the fifo is empty. To avoid that, the solution is to keep a process with the fifo opened in write mode, the 1st cat in the example bellow:

mkfifo in
mkfifo out
cat > out &
echo $! > out-pid
cat out | netcat foo.bar.org 4000 > in &

(The out-pid file is the way to stop the whole thing: kill -9 $(cat out-pid).)

Another example here.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .