Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Pipe a stream to a child process #4374

Closed
thomaspeklak opened this issue Dec 5, 2012 · 8 comments
Closed

Pipe a stream to a child process #4374

thomaspeklak opened this issue Dec 5, 2012 · 8 comments

Comments

@thomaspeklak
Copy link

a child process started with the fork method has only a send method for communication. It would be much nicer if you could pipe directly to the child_process like this:

PARENT

var fs = require('fs');
var fork = require('child_process').fork;

var cp = fork('./child');

fs.createReadStream('./example.txt').pipe(cp);

CHILD

process.write = function(buf){
  process.stdout(buf);
};

process.end = function(buf){
  process.write(buf);
};

Alternatively it would be fine, if you could use fs.createReadStream('./example.txt').pipe(cp.stdin) to achieve the same result. But the forked child process has no stdin.

@TooTallNate
Copy link

Why not just use child_process.spawn()?

@thomaspeklak
Copy link
Author

It seems to me that spawn should be used for node externals like ls, grep, ... and if you use it you would have to do something like this spawn("node", ['child.js']) if understand it right. Rather ugly compared to the simple fork.

As the node community is embracing streams, I thought that it would be much nicer to have this right baked into fork.

@TooTallNate
Copy link

Well fork() is really just a light wrapper around spawn(), only it doesn't let you specify the "stdio" option, which is what you're wanting to alter.

Try something like this:

var args = [ './child.js', /* command arguments */ ];
var child = spawn(process.execPath, args, { stdio: ['pipe', 1, 2, 'ipc'] });
file.pipe(child.stdin);

Which is basically saying "open a new pipe for stdin so I can write to it, share stdout and stderr with this parent process, and open an IPC channel for child.send()/process.send() on FD 4".

@thomaspeklak
Copy link
Author

This works as expected. Still I am not completely satisfied with the situation.

  1. I don't think that this works if the child is a node_module. I think that fork uses the standard way to look for modules but this does not happen in spawn, or am I wrong?
  2. It took me a while to figure out that I could not pipe to a forked child process. I think it should be at least mentioned in the documentation, that this is not possible.

@ypjin
Copy link

ypjin commented Jan 2, 2013

Hello, if spawning the child process like this:
var child = spawn(process.execPath, args, { stdio: [0, 1, 2, 'ipc', 'pipe'] });
How could I reference the pipe in the child process?

@trevnorris
Copy link

@jacobkolind
Copy link

@trevnorris
Copy link

@jacobkolind looks like you've already found a solution.

I'm not still seeing an issue here. If there is one, ping and will discuss.

richardlau pushed a commit to ibmruntimes/node that referenced this issue Feb 29, 2016
* buffer:
  - You can now supply an encoding argument when filling a
    Buffer Buffer#fill(string[, start[, end]][, encoding]), supplying
    an existing Buffer will also work with
    Buffer#fill(buffer[, start[, end]]). See the API documentation for
    details on how this works. (Trevor Norris) nodejs#4935
  - Buffer#indexOf() no longer requires a byteOffset argument if you
    also wish to specify an encoding:
    Buffer#indexOf(val[, byteOffset][, encoding]).
    (Trevor Norris) nodejs#4803
* child_process: spawn() and spawnSync() now support a 'shell' option
  to allow for optional execution of the given command inside a shell.
  If set to true, cmd.exe will be used on Windows and /bin/sh
  elsewhere. A path to a custom shell can also be passed to override
  these defaults. On Windows, this option allows .bat. and .cmd files
  to be executed with spawn() and spawnSync(). (Colin Ihrig) nodejs#4598
* http_parser: Update to http-parser 2.6.2 to fix an unintentionally
  strict limitation of allowable header characters.
  (James M Snell) nodejs#5237
* dgram: socket.send() now supports accepts an array of Buffers or
  Strings as the first argument. See the API docs for details on how
  this works. (Matteo Collina) nodejs#4374
* http: Fix a bug where handling headers will mistakenly trigger an
  'upgrade' event where the server is just advertising its protocols.
  This bug can prevent HTTP clients from communicating with HTTP/2
  enabled servers. (Fedor Indutny) nodejs#4337
* net: Added a listening Boolean property to net and http servers to
  indicate whether the server is listening for connections.
  (José Moreira) nodejs#4743
* node: The C++ node::MakeCallback() API is now reentrant and calling
  it from inside another MakeCallback() call no longer causes the
  nextTick queue or Promises microtask queue to be processed out of
  order. (Trevor Norris) nodejs#4507
* tls: Add a new tlsSocket.getProtocol() method to get the negotiated
  TLS protocol version of the current connection. (Brian White) nodejs#4995
* vm: Introduce new 'produceCachedData' and 'cachedData' options to
  new vm.Script() to interact with V8's code cache. When a new
  vm.Script object is created with the 'produceCachedData' set to true
  a Buffer with V8's code cache data will be produced and stored in
  cachedData property of the returned object. This data in turn may be
  supplied back to another vm.Script() object with a 'cachedData'
  option if the supplied source is the same. Successfully executing a
  script from cached data can speed up instantiation time. See the API
  docs for details. (Fedor Indutny) nodejs#4777
* performance: Improvements in:
  - process.nextTick() (Ruben Bridgewater) nodejs#5092
  - path module (Brian White) nodejs#5123
  - querystring module (Brian White) nodejs#5012
  - streams module when processing small chunks (Matteo Collina) nodejs#4354

PR-URL: nodejs/node#5295
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants