title: Node.js: Capture STDOUT of `child_process.spawn`
body: <p>I need to capture in a custom <strong>stream</strong> outputs of a spawned child process.</p>
  
  <pre><code>child_process.spawn(command[, args][, options])
  </code></pre>
  
  <p>For example,</p>
  
  <pre><code>var s = fs.createWriteStream('/tmp/test.txt');
  child_process.spawn('ifconfig', [], {stdio: [null, s, null]})
  </code></pre>
  
  <p>Now how do I read from the <code>/tmp/test.txt</code> in real time?</p>
  
  <p>It looks like <code>child_process.spawn</code> is not using <code>stream.Writable.prototype.write</code> nor <code>stream.Writable.prototype._write</code> for its execution.</p>
  
  <p>For example,</p>
  
  <pre><code>s.write = function() { console.log("this will never get printed"); };
  </code></pre>
  
  <p>As well as,</p>
  
  <pre><code>s.__proto__._write = function() { console.log("this will never get printed"); };
  </code></pre>
  
  <p>It looks like it uses file descriptors <em>under-the-hood</em> to write from <code>child_process.spawn</code> to a file.</p>
  
  <p>Doing this does not work:</p>
  
  <pre><code>var s2 = fs.createReadStream('/tmp/test.txt');
  s2.on("data", function() { console.log("this will never get printed either"); });
  </code></pre>
  
  <p>So, how can I get the <code>STDOUT</code> contents of a child process?</p>
  
  <p>What I want to achieve is to stream <code>STDOUT</code> of a child process to a socket. If I provide the socket directly to the <code>child_process.spawn</code> as a <code>stdio</code> parameter it closes the socket when it finishes, but I want to keep it open.</p>
  
  <p><strong>Update:</strong></p>
  
  <p>The solution is to use default <code>{stdio: ['pipe', 'pipe', 'pipe']}</code> options and listen to the created <code>.stdout</code> of the child process.</p>
  
  <pre><code>var cmd = child_process.spaw('ifconfig');
  cmd.stdout.on("data", (data) =&gt; { ... });
  </code></pre>
  
  <p>Now, to up the ante, a more challenging question:</p>
  
  <p>-- How do you read the <code>STDOUT</code> of the child process and still preserve the colors?</p>
  
  <p>For example, if you send <code>STDOUT</code> to <code>process.stdout</code> like so:</p>
  
  <pre><code>child_process.spawn('ifconfig', [], {stdio: [null, process.stdout, null]});
  </code></pre>
  
  <p>it will keep the colors and print colored output to the console, because the <code>.isTTY</code> property is set to <code>true</code> on <code>process.stdout</code>.</p>
  
  <pre><code>process.stdout.isTTY // true
  </code></pre>
  
  <p>Now if you use the default <code>{stdio: ['pipe', 'pipe', 'pipe']}</code>, the data you will read will be stripped of console colors. How do you get the colors?</p>
  
  <p>One way to do that would be creating your own custom stream with <code>fs.createWriteStream</code>, because <code>child_process.spawn</code> requires your streams to have a file descriptor.</p>
  
  <p>Then setting <code>.isTTY</code> of that stream to <code>true</code>, to preserve colors.</p>
  
  <p>And finally you would need to capture the data what <code>child_process.spawn</code> writes to that stream, but since <code>child_process.spawn</code> does not use <code>.prototype.write</code> nor <code>.prototype._write</code> of the stream, you would need to capture its contents in some other <em>hacky</em> way.</p>
  
  <p>That's probably why <code>child_process.spawn</code> requires your stream to have a file descriptor because it bypasses the <code>.prototype.write</code> call and writes directly to the file <em>under-the-hood</em>.</p>
  
  <p>Any ideas how to implement this?</p>