Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How to "cross" stdin and stdout of two programs? Specifically, I have 2 programs call pgm1 and pgm2, they are interactive tic-tac-toe games. They both output a number (0to8) indicating position where it wants to mark and expect another number (0to8) indicating where the user wants to mark. The difference between the two is pgm1 makes first move and pgm2 makes second move. They both work fine via interactive user. Can they be made to play against each other using io redirection?

I tried the following things in vain:

  1. Open pgm2 in a separate terminal (it waits for input), find it's pid. Then run pgm1 in another terminal ./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
  2. Made 2 pipes using mkfifo, say pipe1 and pipe2 and ran the following in two different terminals: ./pgm1 < pipe1 > pipe2 and ./pgm2 < pipe2 > pipe1
  3. tried the above two, running pgm1 before pgm2, running pgm2 before pgm1
    I made sure to use fflush(stdout) in both the programs, immediately after using printf().

Could anyone tell me what i am missing / or going wrong / or is this even possible?

share|improve this question

You should be able to get this to work with a FIFO and a pipe.

$ mkfifo fifo
$ ./pgm2 < fifo | ./pgm1 > fifo

Program two's input is the fifo, and outputs to the pipe. Program one's input is the pipe and outputs to the fifo.

Be warned though: this is very racy in general, and can deadlock if the "ping/pong" between the processes isn't perfect.

See also this Stack Overflow question: How to redirect stdout of 2nd process back to stdin of 1st process?

share|improve this answer
Thanks it is working... Just to know, is this not equivalent to the 2nd point that i tried? why is this working while that isn't? – kumar Sep 27 '13 at 9:41

You've got a deadlock in your: ./pgm1 < pipe1 > pipe2 and ./pgm2 < pipe2 > pipe1

The open("pipe1", O_RDONLY) done by the shell prior to executing pgm1 will block until something else does a writing open on that same pipe. Until that's done, it won't do the next open("pipe2", O_WRONLY).

Same for the other one. The open("pipe2", O_RDONLY) will block and because the open("pipe2", O_WRONLY) will not be done since the other shell is waiting for a writer on pipe1, you've got a deadlock.

Had you written it

pgm1 < pipe1 > pipe2 & pgm2 > pipe1 < pipe2

It would have worked.

On Linux, you can also write it:

{ pgm1 <&3 3<&- | pgm2 3<&-; } 3< /dev/fd/1 | :
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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