I have two (UNIX) programs A and B that read and write from stdin/stdout.
My first problem is how to connect the stdout of A to stdin of B and the stdout of B to the stdin of A. I.e., something like A | B but a bidirectional pipe. I suspect I could solve this by using exec to redirect but I could not get it to work. The programs are interactive so a temporary file would not work.
The second problem is that I would like to duplicate each direction and pipe a duplicate via a logging program to stdout so that I can see the (text-line based) traffic that pass between the programs. Here I may get away with tee >(...) if I can solve the first problem.
Both these problems seems like they should have well known solutions but I have not be able to find anything.
I would prefer a POSIX shell solution, or at least something that works in bash on cygwin.
Thanks to your answers I came up with the following solution. The A/B commands uses nc to listen to two ports. The logging program uses sed (with -u for unbuffered processing).
bash-3.2$ fifodir=$(mktemp -d)
bash-3.2$ mkfifo "$fifodir/echoAtoB"
bash-3.2$ mkfifo "$fifodir/echoBtoA"
bash-3.2$ sed -u 's/^/A->B: /' "$fifodir/echoAtoB" &
bash-3.2$ sed -u 's/^/B->A: /' "$fifodir/echoBtoA" &
bash-3.2$ mkfifo "$fifodir/loopback"
bash-3.2$ nc -l -p 47002 < "$fifodir/loopback" \
| tee "$fifodir/echoAtoB" \
| nc -l -p 47001 \
| tee "$fifodir/echoBtoA" > "$fifodir/loopback"
This listens for connection to port 47001 and 47002 and echos all traffic to standard output.
In shell 2 do:
bash-3.2$ nc localhost 47001
In shell 3 do:
bash-3.2$ nc localhost 47002
Now lines entered in shell 2 will be written to shell 3 and vice versa and the traffic logged to shell 1, something like:
B->A: input to port 47001
A->B: input to port 47002
The above has been tested on Cygwin
Update: The script above stopped working after a few days(!). Apparently it can deadlock. Some of the suggestions in the answers may be more reliable.
You can use Expect.
You could use the following code (taken from the Exploring Expect book) as a starting point - it connects the output of proc1 to the input of proc2 and vice versa, as you requested:
I spent a lot of time on this, gave it up, and last decided to use ksh (the Korn shell), which allows this.
where
|&
is a (pipe) operator to start a co-process and&p
is file descriptor of that co-process.I'd suggest "coproc":
Then see this session:
How about a named pipe?
For your second part I believe tee is the correct answer. So it becomes:
I had this problem at one point, and I threw together this simple C program.
This question is similar to one I asked before. The solutions proposed by others were to use named pipes, but I suspect you don't have them in cygwin. Currently I'm sticking to my own (attempt at a) solution, but it requires
/dev/fd/0
which you probably also don't have.Although I don't really like the passing-command-lines-as-strings aspect of
twinpipe
(mentioned by JeeBee (139495)), it might be your only option in cygwin.