title: What is the difference between {} 1>&2 and () 1>&2 in an output-captured function in bash
body: <ol>
  <li><p>with <code>{}</code> - execute while loop in the <strong>current shell</strong></p>
  
  <pre><code>function f {
      {
          while : ; do echo -n a; done  &amp;
      } 1&gt;&amp;2
  }
  
  a=$( f ); echo "returned"
  </code></pre>
  
  <p>-> <code>f()</code> will <em>never</em> return!!!</p></li>
  <li><p><code>()</code> execute while loop in a <strong>subshell</strong></p>
  
  <pre><code>function f {
      (
          while : ; do echo -n a; done  &amp;
      ) 1&gt;&amp;2
  }
  
  a=$( f ); echo "returned"
  </code></pre>
  
  <p>-> <code>f()</code> <em>will</em> return!!!</p></li>
  </ol>
  
  <p><strong>Why?</strong> will one of them return, but not the other? I don't get it...</p>
  
  <hr>
  
  <h2>My analysis:</h2>
  
  <p>The <code>while</code> loop will be forked and start its own background process due to the ending <code>&amp;</code> on the <code>while</code>-loop line. This background process inherits the current open fd list.</p>
  
  <p>As far as I understand, since the <code>while</code> loop is encapsulated, it inherits the encapsulation's fd list. This is how</p>
  
  <pre><code>{ echo log; echo err 1&gt;&amp;2; } 1&gt;l_file 2&gt;e_file
  </code></pre>
  
  <p>works as expected, <code>l_file</code> will contain "log", <code>e_file</code> will contain "err".</p>
  
  <p>So in either the case of <code>{} 1&gt;&amp;2</code> or <code>() 1&gt;&amp;2</code>, bash is informed that it should expect no stdout to capture.</p>
  
  <p>Why is it blocking on the <code>{} 2&gt;&amp;1</code> case?</p>
  
  <ul>
  <li>some evaluation order mystery?</li>
  <li>maybe closing the stdout explicitly would help? I don't know the syntax, though, maybe <code>{} 1&gt;&amp;- 1&gt;&amp;2</code> would help?</li>
  </ul>
  
  <hr>
  
  <p>GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)</p>
  
  <hr>
  
  <h2>EDIT</h2>
  
  <p>Based on the answers so far, I did some more analysis:</p>
  
  <p><strong>11)</strong> <code>{}</code></p>
  
  <pre><code>function f {
      {
          while : ; do echo -n a; done  &amp;
          echo "after loop"
      } 1&gt;&amp;2
      echo "end of function"
  }
  
  a=$( f ); echo "returned"
  </code></pre>
  
  <p>-> <code>after loop</code> is displayed</p>
  
  <p><strong>12)</strong> <code>()</code></p>
  
  <pre><code>function f {
      (
          while : ; do echo -n a; done  &amp;
          echo "after loop"
      ) 1&gt;&amp;2
      echo "end of function"
  }
  
  a=$( f ); echo "returned"
  </code></pre>
  
  <p>-> <code>after loop</code> is displayed</p>
  
  <p>-> <code>returned</code> is displayed</p>