<p>Assume that I have programs <code>P0</code>, <code>P1</code>, ...<code>P(n-1)</code> for some <code>n &gt; 0</code>. How can I easily redirect the output of program <code>Pi</code> to program <code>P(i+1 mod n)</code> for all <code>i</code> (<code>0 &lt;= i &lt; n</code>)?</p>

<p>For example, let's say I have a program <code>square</code>, which repeatedly reads a number and than prints the square of that number, and a program <code>calc</code>, which sometimes prints a number after which it expects to be able to read the square of it. How do I connect these programs such that whenever <code>calc</code> prints a number, <code>square</code> squares it returns it to <code>calc</code>?</p>

<p>Edit: I should probably clarify what I mean with "easily". The named pipe/fifo solution is one that indeed works (and I have used in the past), but it actually requires quite a bit of work to do properly if you compare it with using a bash pipe. (You need to get a not yet existing filename, make a pipe with that name, run the "pipe loop", clean up the named pipe.) Imagine you could no longer write <code>prog1 | prog2</code> and would always have to use named pipes to connect programs.</p>

<p>I'm looking for something that is almost as easy as writing a "normal" pipe. For instance something like <code>{ prog1 | prog2 } &gt;&amp;0</code> would be great.</p>

[{'answer_id': 40339, 'author': 'Mark Witczak', 'author_id': 1536194, 'author_profile': 'https://Stackoverflow.com/users/1536194', 'pm_score': 3, 'selected': False, 'text': "<p>This is a very interesting question. I (vaguely) remember an assignment very similar in college 17 years ago. We had to create an array of pipes, where our code would get filehandles for the input/output of each pipe. Then the code would fork and close the unused filehandles. </p>\n\n<p>I'm thinking you could do something similar with named pipes in bash. Use mknod or mkfifo to create a set of pipes with unique names you can reference then fork your program. </p>\n"}, {'answer_id': 40555, 'author': 'Penz', 'author_id': 4118, 'author_profile': 'https://Stackoverflow.com/users/4118', 'pm_score': -1, 'selected': False, 'text': '<p>I doubt sh/bash can do it.\nZSH would be a better bet, with its MULTIOS and coproc features.</p>\n'}, {'answer_id': 40642, 'author': '1729', 'author_id': 4319, 'author_profile': 'https://Stackoverflow.com/users/4319', 'pm_score': 1, 'selected': False, 'text': '<p>Named pipes.</p>\n\n<p>Create a series of fifos, using mkfifo</p>\n\n<p>i.e fifo0, fifo1</p>\n\n<p>Then attach each process in term to the pipes you want:</p>\n\n<p>processn &lt; fifo(n-1) > fifon</p>\n'}, {'answer_id': 40644, 'author': 'Douglas Leeder', 'author_id': 3978, 'author_profile': 'https://Stackoverflow.com/users/3978', 'pm_score': 4, 'selected': False, 'text': '<p>A named pipe might do it:</p>\n\n<pre><code>$ mkfifo outside\n$ &lt;outside calc | square &gt;outside &amp;\n$ echo "1" &gt;outside ## Trigger the loop to start\n</code></pre>\n'}, {'answer_id': 43332, 'author': 'mweerden', 'author_id': 4285, 'author_profile': 'https://Stackoverflow.com/users/4285', 'pm_score': 5, 'selected': False, 'text': '<p>After spending quite some time yesterday trying to redirect <code>stdout</code> to <code>stdin</code>, I ended up with the following method. It isn\'t really nice, but I think I prefer it over the named pipe/fifo solution.</p>\n\n<pre><code>read | { P0 | ... | P(n-1); } &gt;/dev/fd/0\n</code></pre>\n\n<p>The <code>{ ... } &gt;/dev/fd/0</code> is to redirect stdout to stdin for the pipe sequence as a whole (i.e. it redirects the output of P(n-1) to the input of P0). Using <code>&gt;&amp;0</code> or something similar does not work; this is probably because bash assumes <code>0</code> is read-only while it doesn\'t mind writing to <code>/dev/fd/0</code>.</p>\n\n<p>The initial <code>read</code>-pipe is necessary because without it both the input and output file descriptor are the same pts device (at least on my system) and the redirect has no effect. (The pts device doesn\'t work as a pipe; writing to it puts things on your screen.) By making the input of the <code>{ ... }</code> a normal pipe, the redirect has the desired effect.</p>\n\n<p>To illustrate with my <code>calc</code>/<code>square</code> example:</p>\n\n<pre><code>function calc() {\n  # calculate sum of squares of numbers 0,..,10\n\n  sum=0\n  for ((i=0; i&lt;10; i++)); do\n    echo $i                   # "request" the square of i\n\n    read ii                   # read the square of i\n    echo "got $ii" &gt;&amp;2          # debug message\n\n    let sum=$sum+$ii\n  done\n\n  echo "sum $sum" &gt;&amp;2           # output result to stderr\n}\n\nfunction square() {\n  # square numbers\n\n  read j                         # receive first "request"\n  while [ "$j" != "" ]; do\n    let jj=$j*$j\n    echo "square($j) = $jj" &gt;&amp;2  # debug message\n\n    echo $jj                     # send square\n\n    read j                       # receive next "request"\n  done\n}\n\nread | { calc | square; } &gt;/dev/fd/0\n</code></pre>\n\n<p>Running the above code gives the following output:</p>\n\n<pre><code>square(0) = 0\ngot 0\nsquare(1) = 1\ngot 1\nsquare(2) = 4\ngot 4\nsquare(3) = 9\ngot 9\nsquare(4) = 16\ngot 16\nsquare(5) = 25\ngot 25\nsquare(6) = 36\ngot 36\nsquare(7) = 49\ngot 49\nsquare(8) = 64\ngot 64\nsquare(9) = 81\ngot 81\nsum 285\n</code></pre>\n\n<p>Of course, this method is quite a bit of a hack. Especially the <code>read</code> part has an undesired side-effect: termination of the "real" pipe loop does not lead to termination of the whole. I couldn\'t think of anything better than <code>read</code> as it seems that you can only determine that the pipe loop has terminated by try to writing write something to it.</p>\n'}, {'answer_id': 464638, 'author': 'Fritz G. Mehner', 'author_id': 57457, 'author_profile': 'https://Stackoverflow.com/users/57457', 'pm_score': -1, 'selected': False, 'text': '<p>A command stack can be composed as string from an array of arbitrary commands\nand evaluated with eval. The following example gives the result  65536.</p>\n\n<pre><code>function square ()\n{\n  read n\n  echo $((n*n))\n}    # ----------  end of function square  ----------\n\ndeclare -a  commands=( \'echo 4\' \'square\' \'square\' \'square\' )\n\n#-------------------------------------------------------------------------------\n#   build the command stack using pipes\n#-------------------------------------------------------------------------------\ndeclare     stack=${commands[0]}\n\nfor (( COUNTER=1; COUNTER&lt;${#commands[@]}; COUNTER++ )); do\n  stack="${stack} | ${commands[${COUNTER}]}"\ndone\n\n#-------------------------------------------------------------------------------\n#   run the command stack\n#-------------------------------------------------------------------------------\neval "$stack" \n</code></pre>\n'}, {'answer_id': 29053837, 'author': 'Andreas Florath', 'author_id': 1247301, 'author_profile': 'https://Stackoverflow.com/users/1247301', 'pm_score': 2, 'selected': False, 'text': '<p>My solutions uses <a href="https://github.com/flonatel/pipexec" rel="nofollow">pipexec</a> (Most of the function implementation comes from your answer):</p>\n\n<p>square.sh</p>\n\n<pre><code>function square() {\n  # square numbers\n\n  read j                         # receive first "request"\n  while [ "$j" != "" ]; do\n    let jj=$j*$j\n    echo "square($j) = $jj" &gt;&amp;2  # debug message\n\n    echo $jj                     # send square\n\n    read j                       # receive next "request"\n  done\n}\n\nsquare $@\n</code></pre>\n\n<p>calc.sh</p>\n\n<pre><code>function calc() {\n  # calculate sum of squares of numbers 0,..,10\n\n  sum=0\n  for ((i=0; i&lt;10; i++)); do\n    echo $i                   # "request" the square of i\n\n    read ii                   # read the square of i\n    echo "got $ii" &gt;&amp;2          # debug message\n\n    let sum=$sum+$ii\n done\n\n echo "sum $sum" &gt;&amp;2           # output result to stderr\n}\n\ncalc $@\n</code></pre>\n\n<p>The command</p>\n\n<pre><code>pipexec [ CALC /bin/bash calc.sh ] [ SQUARE /bin/bash square.sh ] \\\n    "{CALC:1&gt;SQUARE:0}" "{SQUARE:1&gt;CALC:0}"\n</code></pre>\n\n<p>The output (same as in your answer)</p>\n\n<pre><code>square(0) = 0\ngot 0\nsquare(1) = 1\ngot 1\nsquare(2) = 4\ngot 4\nsquare(3) = 9\ngot 9\nsquare(4) = 16\ngot 16\nsquare(5) = 25\ngot 25\nsquare(6) = 36\ngot 36\nsquare(7) = 49\ngot 49\nsquare(8) = 64\ngot 64\nsquare(9) = 81\ngot 81\nsum 285\n</code></pre>\n\n<p>Comment: pipexec was designed to start processes and build arbitrary pipes in between.  Because bash functions cannot be handled as processes, there is the need to have the functions in separate files and use a separate bash.</p>\n'}]
['https://Stackoverflow.com/questions/40244', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4285/']