0

I have two binaries, one (questions.bin) throws questions like "What's 1+3?" to STDOUT and gets answers from STDIN; the other, answers.bin, takes questions in STDIN in the above format and prints them to STDOUT.

I wanted to be able to pipe the outputs of them to each other, something like

./questions.bin | ./answers.bin | ./questions.bin

Is there any way to do that with piping? If not, how would you do it otherwise?

gmelodie
  • 131
  • 1
    Shell pipes will only be set up in a linear form, because that's all the syntax permits you to do. You could set up two named pipes (with mkfifo), and set up each program to read from one and write to the other. There can be flow control issues with this method, where both programs are waiting for the other to continue the conversation. Some mechanism to terminate each exchange is useful (similar to the "over" "over and out" used for CB radio). – Paul_Pedant Aug 14 '21 at 22:41

2 Answers2

3

As it turns out, that's a simple case of using named pipes. Here's a modified example I got from this answer:

mkfifo backpipe
./questions.bin 0<backpipe | ./answers.bin 1>backpipe
gmelodie
  • 131
  • That works for one-line transactions: the processes stay in sync because they each read one line, write one line. If the transaction can produce a variable response (say, questions issues SQL queries and answers sends the results) then questions needs to know when it won't get any more input until it starts a new transaction, and answers needs to know when it has received the last line of a multiline query. Both data sets need some data framing framing protocol to avoid deadlocks. – Paul_Pedant Aug 15 '21 at 11:32
1

On Linux, you can use the property of /dev/fd/x which where fd x refers to a pipe, behaves like a named pipe:

: | (./questions.bin | ./answers.bin) > /dev/fd/0

The yash shell has a raw interface to the pipe() system call via its pipeline redirection feature:

(./questions.bin | ./answers.bin) >>|0

Those avoid having to create named pipes (and the associated concerns with guaranteeing exclusive creation, restricting access to them, and clean-up afterwards or upon signals).