<p>I'd like to redirect the stdout of process proc1 to two processes proc2 and proc3:</p>

<pre><code>         proc2 -&gt; stdout
       /
 proc1
       \ 
         proc3 -&gt; stdout
</code></pre>

<p>I tried</p>

<pre><code> proc1 | (proc2 &amp; proc3)
</code></pre>

<p>but it doesn't seem to work, i.e.</p>

<pre><code> echo 123 | (tr 1 a &amp; tr 1 b)
</code></pre>

<p>writes</p>

<pre><code> b23
</code></pre>

<p>to stdout instead of </p>

<pre><code> a23
 b23
</code></pre>

[{'answer_id': 60955, 'author': 'dF.', 'author_id': 3002, 'author_profile': 'https://Stackoverflow.com/users/3002', 'pm_score': 8, 'selected': True, 'text': '<p><sup><em>Editor\'s note</em>:<br>\n - <code>&gt;(…)</code> is a <a href="http://mywiki.wooledge.org/ProcessSubstitution" rel="noreferrer"><em>process substitution</em></a> that is a <em>nonstandard shell feature</em> of <em>some</em> POSIX-compatible shells: <code>bash</code>, <code>ksh</code>, <code>zsh</code>.<br>\n - This answer accidentally sends the output process substitution\'s output through the pipeline <em>too</em>: <code>echo 123 | tee &gt;(tr 1 a) | tr 1 b</code>.<br>\n - Output from the process substitutions will be unpredictably interleaved, and, except in <code>zsh</code>, the pipeline may terminate before the commands inside <code>&gt;(…)</code> do.</sup></p>\n\n<p>In unix (or on a mac), use the <a href="http://en.wikipedia.org/wiki/Tee_(command)" rel="noreferrer"><code>tee</code> command</a>:</p>\n\n<pre><code>$ echo 123 | tee &gt;(tr 1 a) &gt;(tr 1 b) &gt;/dev/null\nb23\na23\n</code></pre>\n\n<p>Usually you would use <code>tee</code> to redirect output to multiple files, but using >(...) you can\nredirect to another process. So, in general,</p>\n\n<pre><code>$ proc1 | tee &gt;(proc2) ... &gt;(procN-1) &gt;(procN) &gt;/dev/null\n</code></pre>\n\n<p>will do what you want.</p>\n\n<p>Under windows, I don\'t think the built-in shell has an equivalent. Microsoft\'s <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx" rel="noreferrer">Windows PowerShell</a> has a <code>tee</code> command though.  </p>\n'}, {'answer_id': 61716, 'author': 'Jay Bazuzi', 'author_id': 5314, 'author_profile': 'https://Stackoverflow.com/users/5314', 'pm_score': 3, 'selected': False, 'text': '<p>Since @dF: mentioned that PowerShell has tee, I thought I\'d show a way to do this in PowerShell.  </p>\n\n<pre><code>PS &gt; "123" | % { \n    $_.Replace( "1", "a"), \n    $_.Replace( "2", "b" ) \n}\n\na23\n1b3\n</code></pre>\n\n<p>Note that each object coming out of the first command is processed before the next object is created.  This can allow scaling to very large inputs.</p>\n'}, {'answer_id': 190777, 'author': 'tzot', 'author_id': 6899, 'author_profile': 'https://Stackoverflow.com/users/6899', 'pm_score': 5, 'selected': False, 'text': '<p>Like dF said, <code>bash</code> allows to use the <code>&gt;(…)</code> construct running a command in place of a filename. (There is also the <code>&lt;(…)</code> construct to substitute the <em>output</em> of another command in place of a filename, but that is irrelevant now, I mention it just for completeness).</p>\n\n<p>If you don\'t have bash, or running on a system with an older version of bash, you can do manually what bash does, by making use of FIFO files.</p>\n\n<p>The generic way to achieve what you want, is:</p>\n\n<ul>\n<li>decide how many processes should receive the output of your command, and create as many FIFOs, preferably on a global temporary folder:  </li>\n</ul>\n\n<pre>\n    subprocesses="a b c d"\n    mypid=$$\n    for i in $subprocesses # this way we are compatible with all sh-derived shells  \n    do\n        mkfifo /tmp/pipe.$mypid.$i\n    done\n</pre>\n\n<ul>\n<li>start all your subprocesses waiting input from the FIFOs:</li>\n</ul>\n\n<pre>\n    for i in $subprocesses\n    do\n        tr 1 $i &lt;/tmp/pipe.$mypid.$i & # background!\n    done\n</pre>\n\n<ul>\n<li>execute your command teeing to the FIFOs:</li>\n</ul>\n\n<pre>\n    proc1 | tee $(for i in $subprocesses; do echo /tmp/pipe.$mypid.$i; done)\n</pre>\n\n<ul>\n<li>finally, remove the FIFOs:</li>\n</ul>\n\n<pre>\n    for i in $subprocesses; do rm /tmp/pipe.$mypid.$i; done\n</pre>\n\n<p>NOTE: for compatibility reasons, I would do the <code>$(…)</code> with backquotes, but I couldn\'t do it writing this answer (the backquote is used in SO). Normally, the <code>$(…)</code> is old enough to work even in old versions of ksh, but if it doesn\'t, enclose the <code>…</code> part in backquotes.</p>\n'}, {'answer_id': 16541914, 'author': 'munish', 'author_id': 730858, 'author_profile': 'https://Stackoverflow.com/users/730858', 'pm_score': -1, 'selected': False, 'text': "<p>another way to do would be,</p>\n\n<pre><code> eval `echo '&amp;&amp; echo 123 |'{'tr 1 a','tr 1 b'} | sed -n 's/^&amp;&amp;//gp'`\n</code></pre>\n\n<p>output:</p>\n\n<pre><code>a23\nb23\n</code></pre>\n\n<p>no need to create a subshell here</p>\n"}, {'answer_id': 43906764, 'author': 'mklement0', 'author_id': 45375, 'author_profile': 'https://Stackoverflow.com/users/45375', 'pm_score': 4, 'selected': False, 'text': '<h3>Unix (<code>bash</code>, <code>ksh</code>, <code>zsh</code>)</h3>\n\n<p><a href="https://stackoverflow.com/q/60942/45375">dF.\'s answer</a> contains the <em>seed</em> of an answer based on <code>tee</code> and <em>output</em> <a href="http://mywiki.wooledge.org/ProcessSubstitution" rel="noreferrer">process substitutions</a><br>\n(<code>&gt;(...)</code>) that <em>may or may not</em> work, depending on your requirements:</p>\n\n<p><sup>Note that process substitutions are a <em>nonstandard</em> feature that (mostly)\n POSIX-features-only shells such as <code>dash</code> (which acts as <code>/bin/sh</code> on Ubuntu,\n for instance), do <em>not</em> support. Shell scripts targeting <code>/bin/sh</code> should <em>not</em> rely on them.</sup></p>\n\n<pre><code>echo 123 | tee &gt;(tr 1 a) &gt;(tr 1 b) &gt;/dev/null\n</code></pre>\n\n<p>The <strong>pitfalls</strong> of this approach are:</p>\n\n<ul>\n<li><p><strong>unpredictable, asynchronous output behavior</strong>:  the output streams from the commands inside the output process substitutions <code>&gt;(...)</code> interleave in unpredictable ways.</p></li>\n<li><p>In <code>bash</code> and <code>ksh</code> (as opposed to <code>zsh</code> - but see exception below):</p>\n\n<ul>\n<li><strong>output may  arrive <em>after</em> the command has finished.</strong></li>\n<li><strong>subsequent commands may start executing <em>before</em> the commands in the process substitutions have finished</strong> - <code>bash</code> and <code>ksh</code> do <em>not</em> wait for the output process substitution-spawned processes to finish, at least by default.  </li>\n<li><a href="https://stackoverflow.com/users/173250/jmb">jmb</a> puts it well in a comment on dF.\'s answer:</li>\n</ul></li>\n</ul>\n\n<blockquote>\n  <p>be aware that the commands started inside <code>&gt;(...)</code> are dissociated from the original shell, and you can\'t easily determine when they finish; the <code>tee</code> will finish after writing everything, but the substituted processes will still be consuming the data from various buffers in the kernel and file I/O, plus whatever time is taken by their internal handling of data. You can encounter race conditions if your outer shell then goes on to rely on anything produced by the sub-processes.</p>\n</blockquote>\n\n<ul>\n<li><p><strong><code>zsh</code></strong> is the only shell that <strong><em>does</em> by default wait for the processes run in the output process substitutions to finish</strong>, <em>except</em> if it is <em>stderr</em> that is redirected to one (<code>2&gt; &gt;(...)</code>).</p></li>\n<li><p><strong><code>ksh</code></strong> (at least as of version <code>93u+</code>) allows use of argument-less <code>wait</code> to wait for the output process substitution-spawned processes to finish.<br>\nNote that in an interactive session that could result in waiting for any pending <em>background jobs</em> too, however.</p></li>\n<li><p><strong><code>bash v4.4+</code></strong> can wait for the <em>most recently</em> launched output process substitution with <code>wait $!</code>, but argument-less <code>wait</code> does <em>not</em> work, making this unsuitable for a command with <em>multiple</em> output process substitutions.</p></li>\n<li><p>However, <strong><code>bash</code> and <code>ksh</code> can be <em>forced</em> to wait</strong> by piping the command to <strong><code>| cat</code></strong>, but note that this makes the command run in a <em>subshell</em>. <em>Caveats</em>:</p>\n\n<ul>\n<li><p><code>ksh</code> (as of <code>ksh 93u+</code>) doesn\'t support sending <em>stderr</em> to an output process substitution (<code>2&gt; &gt;(...)</code>); such an attempt is <em>silently ignored</em>.</p></li>\n<li><p>While <code>zsh</code> is (commendably) synchronous <em>by default</em> with the (far more common) <em>stdout</em> output process substitutions, even the <code>| cat</code> technique cannot make them synchronous with <em>stderr</em> output process substitutions (<code>2&gt; &gt;(...)</code>).</p></li>\n</ul></li>\n<li><p>However, <strong>even if you ensure <em>synchronous execution</em>, the problem of <em>unpredictably interleaved output</em> remains.</strong></p></li>\n</ul>\n\n<p>The following command, when run in <code>bash</code> or <code>ksh</code>, illustrates the problematic behaviors (you may have to run it several times to see <em>both</em> symptoms): The <code>AFTER</code> will typically print <em>before</em> output from the output substitutions, and the output from the latter can be interleaved unpredictably.</p>\n\n<pre><code>printf \'line %s\\n\' {1..30} | tee &gt;(cat -n) &gt;(cat -n) &gt;/dev/null; echo AFTER\n</code></pre>\n\n<p><strong>In short</strong>:</p>\n\n<ul>\n<li><p>Guaranteeing a particular per-command output sequence:</p>\n\n<ul>\n<li>Neither <code>bash</code> nor <code>ksh</code> nor <code>zsh</code> support that.</li>\n</ul></li>\n<li><p>Synchronous execution:</p>\n\n<ul>\n<li>Doable, except with <em>stderr</em>-sourced output process substitutions:\n\n<ul>\n<li>In <code>zsh</code>, they\'re <em>invariably</em> asynchronous.</li>\n<li>In <code>ksh</code>, they <em>don\'t work at all</em>.</li>\n</ul></li>\n</ul></li>\n</ul>\n\n<p>If you can live with these limitations, using output process substitutions is a viable option (e.g., if all of them write to separate output files).</p>\n\n<hr>\n\n<p>Note that <strong><a href="https://stackoverflow.com/a/190777/45375">tzot\'s much more cumbersome, but potentially POSIX-compliant solution</a> also exhibits unpredictable output behavior</strong>; however, by using <code>wait</code> you can ensure that subsequent commands do not start executing until all background processes have finished.<br>\n<strong>See bottom</strong> for <strong>a more robust, synchronous, serialized-output implementation</strong>.</p>\n\n<hr>\n\n<p><strong>The only <em>straightforward</em> <code>bash</code> solution <em>with predictable output behavior</em></strong> is the following, which, however, is <strong>prohibitively slow with large input sets</strong>, because shell loops are inherently slow.<br>\nAlso note that this <strong><em>alternates</em> the output lines from the target commands</strong>.</p>\n\n<pre><code>while IFS= read -r line; do \n  tr 1 a &lt;&lt;&lt;"$line"\n  tr 1 b &lt;&lt;&lt;"$line"\ndone &lt; &lt;(echo \'123\')\n</code></pre>\n\n<hr>\n\n<h3>Unix (using GNU Parallel)</h3>\n\n<p>Installing <a href="https://www.gnu.org/software/parallel/" rel="noreferrer">GNU <code>parallel</code></a> enables a <strong>robust solution</strong> with <strong>serialized (per-command) output</strong> that additionally allows <strong>parallel execution</strong>:</p>\n\n<pre><code>$ echo \'123\' | parallel --pipe --tee {} ::: \'tr 1 a\' \'tr 1 b\'\na23\nb23\n</code></pre>\n\n<p><code>parallel</code> by default ensures that output from the different commands doesn\'t interleave (this behavior can be modified - see <code>man parallel</code>).</p>\n\n<p><sup>Note: Some Linux distros come with a <em>different</em> <code>parallel</code> utility, which won\'t work with the command above; use <code>parallel --version</code> to determine which one, if any, you have.</sup></p>\n\n<hr>\n\n<h3>Windows</h3>\n\n<p><a href="https://stackoverflow.com/a/61716/45375">Jay Bazuzi\'s helpful answer</a> shows how to do it in <strong>PowerShell</strong>. That said: his answer is the analog of the looping <code>bash</code> answer above, it will be <strong>prohibitively slow with large input sets</strong> and also <strong><em>alternates</em> the output lines from the target commands</strong>.</p>\n\n<hr>\n\n<hr>\n\n<h3><code>bash</code>-based, but otherwise portable Unix solution with synchronous execution and output serialization</h3>\n\n<p>The following is a simple, but reasonably robust implementation of the approach presented in <a href="https://stackoverflow.com/a/190777/45375">tzot\'s answer</a> that additionally provides:</p>\n\n<ul>\n<li>synchronous execution</li>\n<li>serialized (grouped) output</li>\n</ul>\n\n<p>While not strictly POSIX compliant, because it is a <code>bash</code> script, it should be <strong>portable to any Unix platform that has <code>bash</code></strong>.</p>\n\n<p>Note: You can find a more full-fledged implementation released under the MIT license in <a href="https://gist.github.com/mklement0/a9ca81f1d4e170fc1544706147663f64" rel="noreferrer">this Gist</a>.</p>\n\n<p>If you save the code below as script <code>fanout</code>, make it executable and put int your <code>PATH</code>, the command from the question would work as follows:</p>\n\n<pre><code>$ echo 123 | fanout \'tr 1 a\' \'tr 1 b\'\n# tr 1 a\na23\n# tr 1 b\nb23\n</code></pre>\n\n<p><strong><code>fanout</code> script source code</strong>:</p>\n\n<pre><code>#!/usr/bin/env bash\n\n# The commands to pipe to, passed as a single string each.\naCmds=( "$@" )\n\n# Create a temp. directory to hold all FIFOs and captured output.\ntmpDir="${TMPDIR:-/tmp}/$kTHIS_NAME-$$-$(date +%s)-$RANDOM"\nmkdir "$tmpDir" || exit\n# Set up a trap that automatically removes the temp dir. when this script\n# exits.\ntrap \'rm -rf "$tmpDir"\' EXIT \n\n# Determine the number padding for the sequential FIFO / output-capture names, \n# so that *alphabetic* sorting, as done by *globbing* is equivalent to\n# *numerical* sorting.\nmaxNdx=$(( $# - 1 ))\nfmtString="%0${#maxNdx}d"\n\n# Create the FIFO and output-capture filename arrays\naFifos=() aOutFiles=()\nfor (( i = 0; i &lt;= maxNdx; ++i )); do\n  printf -v suffix "$fmtString" $i\n  aFifos[i]="$tmpDir/fifo-$suffix"\n  aOutFiles[i]="$tmpDir/out-$suffix"\ndone\n\n# Create the FIFOs.\nmkfifo "${aFifos[@]}" || exit\n\n# Start all commands in the background, each reading from a dedicated FIFO.\nfor (( i = 0; i &lt;= maxNdx; ++i )); do\n  fifo=${aFifos[i]}\n  outFile=${aOutFiles[i]}\n  cmd=${aCmds[i]}\n  printf \'# %s\\n\' "$cmd" &gt; "$outFile"\n  eval "$cmd" &lt; "$fifo" &gt;&gt; "$outFile" &amp;\ndone\n\n# Now tee stdin to all FIFOs.\ntee "${aFifos[@]}" &gt;/dev/null || exit\n\n# Wait for all background processes to finish.\nwait\n\n# Print all captured stdout output, grouped by target command, in sequences.\ncat "${aOutFiles[@]}"\n</code></pre>\n'}, {'answer_id': 62188317, 'author': 'exic', 'author_id': 332451, 'author_profile': 'https://Stackoverflow.com/users/332451', 'pm_score': 1, 'selected': False, 'text': '<p>You can also save the output in a variable and use that for the other processes:</p>\n\n<pre><code>out=$(proc1); echo "$out" | proc2; echo "$out" | proc3\n</code></pre>\n\n<p>However, that works only if </p>\n\n<ol>\n<li><code>proc1</code> terminates at some point :-)</li>\n<li><code>proc1</code> doesn\'t produce too much output (don\'t know what the limits are there but it\'s probably your RAM)</li>\n</ol>\n\n<p>But it is easy to remember and leaves you with more options on the output you get from the processes you spawned there, e. g.:</p>\n\n<pre><code>out=$(proc1); echo $(echo "$out" | proc2) / $(echo "$out" | proc3) | bc\n</code></pre>\n\n<p>I had difficulties doing something like that with the <code>| tee &gt;(proc2) &gt;(proc3) &gt;/dev/null</code> approach.</p>\n'}]
['https://Stackoverflow.com/questions/60942', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4085/']