node.js: How to spawn detached child in foreground and exit
Asked Answered
J

2

12

According to the docs for child_process.spawn I would expect to be able to run a child process in the foreground and allow the node process itself to exit like so:

handoff-exec.js:

'use strict';

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

// this console.log before the spawn seems to cause
// the child to exit immediately, but putting it
// afterwards seems to not affect it.
//console.log('hello');

var child = spawn(
  'ping'
, [ '-c', '3', 'google.com' ]
, { detached: true, stdio: 'inherit' }
);

child.unref();

Instead of seeing the output of the ping command, it simply exits without any message or error.

node handoff-exec.js
hello
echo $?
0

So... is it possible in node.js (or at all) to run a child in the foreground as the parent exits?

Buggy Node Versions

I found that removing console.log('hello'); allows the child to run, however, it still doesn't pass foreground stdin control to the child. That's obviously not intended, therefore something must be buggy in the version of node I was using at the time...

https://github.com/nodejs/node/issues/5549

Jinks answered 3/3, 2016 at 9:20 Comment(3)
Possible duplicate of How do I listen and spawn multiple child process in nodejsMacswan
Nope. That was about using a closure in JavaScript to capture the JS references to multiple child processes. This is about process references and letting the child take control of standard input.Jinks
For what it's worth, I tried running your code and it worked as expected for me - the node process exited, and the ping command output was printed to stdout. This is on Mac OS and node.js v5.4.1. It doesn't work if I uncomment the console.log - which I find very strange.Incursion
J
1

Solution

The code in the question was actually correct. There was a legitimate bug in node at the time.

'use strict';

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

console.log("Node says hello. Let's see what ping has to say...");

var child = spawn(
  'ping'
, [ '-c', '3', 'google.com' ]
, { detached: true, stdio: 'inherit' }
);

child.unref();

The snippet above will run effectively the same as if it had been backgrounded by the shell:

ping -c 3 google.com &
Jinks answered 16/8, 2019 at 17:16 Comment(1)
I don't get any output from ping. Node v16, Windows (tested with cmd and with git bash). I read a node GitHub issue claiming that it is expected that when using "detached" that the output will NOT work, because the process also detaches the terminal: github.com/nodejs/node/issues/3596Jukebox
O
-2

You are missing

// Listen for any response:
child.stdout.on('data', function (data) {
    console.log(data.toString());
});

// Listen for any errors:
child.stderr.on('data', function (data) {
    console.log(data.toString());
}); 

and you don't need the child.unref();

Overdraft answered 27/7, 2017 at 2:45 Comment(1)
That would cause the parent process to continue to run.Jinks

© 2022 - 2024 — McMap. All rights reserved.