1

Let's say I got two programs: program1 and program2. I want to take the output of program1, put it into input of program2, then take output of program2 and put it into input of program1 etc.

How should bash script doing this look like? I've read a lot about pipes and input/output redirection, but I'm still not sure. Is it possible to use one pipe both for input and output of program2, and another one for program2?

I've written something like this:

PIPE=$(mktemp -u)
mkfifo $PIPE
exec 3<>$PIPE
rm $PIPE 
cat <&3 >&3 &

But when I want to run program1 and program2 like this:

cat <&3 | ./program1 >&3 &
cat <&3 | ./program2 >&3 &

It doesn't work. Any clues what should I do? Thank you in advance :)

1
  • you ran it on the background... Commented May 28, 2016 at 23:35

1 Answer 1

3

Yes, we can loop output of a pipeline back to its input using a FIFO. Here's how.

First, let's create a fifo (named pipe):

$ mkfifo pipe

Let's also, for demonstration purposes, create shell functions to use in the pipeline:

$ p1() { while read a; do sleep 0.1; echo "$((a+1))"; done; }
$ p2() { while read b; do echo "$((b+1))"; done | tee /dev/stderr; }

Now, let's run them with p1 feeding its output to p2 which sends its output to pipe which is fed back to the input of p1:

$ { echo 1; cat pipe; } | p1 | p2 >pipe
3
5
7
9
11
13
^C

The loop would go on forever but I terminated it with a ctrl-C first. p1 increments its input by one and p2 increments its input by one. The output we see comes from the stderr stream of p2.

How it works

{ echo 1; cat pipe; } provides the input to p1. It provides a 1 as a seed value and then supplies whatever it receives from pipe.

p1 works as follows:

while read a
do
    sleep 0.1
    echo "$((a+1))"
done

It reads from its input, waits 0.1 seconds, and writes an incremented value to its stdout. The purpose of the short wait is so that the output does not scroll by too fast on the screen.

p2 works as follows:

while read b
do
    echo "$((b+1))"
done | tee /dev/stderr

Just like p1, it reads from stdin and writes an incremented value to stdout. So that we can see what's going on on the terminal, this also sends a copy of the output to stderr.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.