Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The process never ends when piping the stdin to a child process #2276

Closed
IonicaBizau opened this issue Jul 30, 2015 · 10 comments
Closed

The process never ends when piping the stdin to a child process #2276

IonicaBizau opened this issue Jul 30, 2015 · 10 comments
Labels
child_process Issues and PRs related to the child_process subsystem. process Issues and PRs related to the process subsystem.

Comments

@IonicaBizau
Copy link
Contributor

Initially I asked this on StackOverflow, but looks like a bug (nodejs/node-v0.x-archive#9190). Post follows:


I'm using spawn to create a child process and pipe data:

child process  |  parent process (main)
---------------------------------------
stdout      ----->       process.stdout
stderr      ----->       process.stderr
stdin       <-----        process.stdin

The problem is that when piping the process.stdin to the child process stdin, the main process is not ended when the child process is finished.

The code looks like this (not a really good example because ps does not use stdin data, I guess):

var Spawn = require("child_process").spawn;

var ps = Spawn("ps");
process.stdin.pipe(ps.stdin);
ps.stdout.pipe(process.stdout);
ps.stderr.pipe(process.stderr);

If I remove the process.stdin.pipe(ps.stdin) line, the main process is ended, but the stdin data is not piped anymore.

Why isn't the main process ended when the ps child process is ended? How can I solve this problem?

An ugly solution would be:

ps.on("close", process.exit.bind(process));

I don't like this, because I don't really want to force the main process to be closed, but I want to be closed naturally (e.g. having setTimeout(function(){}, 1000) you wait 1000ms and then the process ends).


I tried to ps.stdin.close() in ps.on("close", cb). It didn't work... 😢

@targos
Copy link
Member

targos commented Jul 30, 2015

Your example works fine with a command that uses stdin like cat:

var Spawn = require('child_process').spawn;

var ps = Spawn('cat');
process.stdin.pipe(ps.stdin);
ps.stdout.pipe(process.stdout);
ps.stderr.pipe(process.stderr);
% echo "abc" | node test.js
abc

We may need more information about the context of your problem, in order to help further.

@Fishrock123 Fishrock123 added child_process Issues and PRs related to the child_process subsystem. process Issues and PRs related to the process subsystem. labels Jul 30, 2015
@Fishrock123
Copy link
Contributor

Does ps actually consume the stdin that is piped to it?

Edit: Maybe ps doesn't close when it's being piped to unless you tell it to?

@IonicaBizau
Copy link
Contributor Author

@targos Interesting! If I pipe data to the process, it's closed:

The code is:

var Spawn = require("child_process").spawn;

var ps = Spawn('cat');
process.stdin.pipe(ps.stdin);
ps.stdout.pipe(process.stdout);
ps.stderr.pipe(process.stderr);

ps.on("close", function () {
    console.log("Closed");
});

And the result is:

$ echo "foo" | node index.js 
foo
Closed

If I don't pipe anything, the process is not closed, which is fine in this case because the child process is not closed (it still listens for data).

However, in the pscase (just replace cat with ps in the code above) there is a strange behavior:

$ node index.js # This does not close the main process, even the child process is closed
  PID TTY          TIME CMD
 9021 pts/23   00:00:00 node
 9026 pts/23   00:00:00 ps
30815 pts/23   00:00:00 bash
Closed
^C
$ echo "foo" | node index.js 
  PID TTY          TIME CMD
12728 pts/23   00:00:00 node
12733 pts/23   00:00:00 ps
30815 pts/23   00:00:00 bash
Closed
$ echo "foo" | node index.js 
  PID TTY          TIME CMD
12735 pts/23   00:00:00 node
12740 pts/23   00:00:00 ps
30815 pts/23   00:00:00 bash
Closed
$ echo "foo" | node index.js 
events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: write EPIPE
    at exports._errnoException (util.js:746:11)
    at WriteWrap.afterWrite (net.js:766:14)

Why does the EPIPE error appears randomly?

We may need more information about the context of your problem, in order to help further.

I'm happy to provide more information, just ask me. 😸

@Fishrock123 Yeah, probable it doesn't use the stdin data, but the child process is closed -- while the parent still remains alive.

@IonicaBizau IonicaBizau changed the title NodeJS process never ends when piping the stdin to a child process The process never ends when piping the stdin to a child process Jul 30, 2015
@IonicaBizau
Copy link
Contributor Author

I'm not sure, but I guess we could say that if the stdin data is not consumed in the child process, then the main process never ends, even the child process does.

@IonicaBizau
Copy link
Contributor Author

Any feedback on this?

@Fishrock123
Copy link
Contributor

@IonicaBizau hmmm, that looks like #947?

(Which fwiw, is a pretty tricky issue.)

@IonicaBizau
Copy link
Contributor Author

@Fishrock123 Ah, actually, yes. Thanks.

@masaeedu
Copy link

I'm still seeing this issue in Node v10.3.0, was this supposed to be resolved in #947?

@masaeedu
Copy link

The issue being that if you create a child process and pipe the parent's stdin to the child, the parent never dies even if the child does.

@sam-github
Copy link
Contributor

I'm a bit confused by the current state of this, you seem to show this is not a problem with cat, but is with ps, in which case the problem isn't with the node parent but with the behaviour of the non-node child, isn't it?

ps is special, and has odd behaviour wrt. to stdin, cf #24327 (comment).

Can you provide a small self-contained example and a description of how the examples behaviour differs from your expectation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
child_process Issues and PRs related to the child_process subsystem. process Issues and PRs related to the process subsystem.
Projects
None yet
Development

No branches or pull requests

5 participants