11

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...

coolaj86
  • 64,368
  • 14
  • 90
  • 108
  • Possible duplicate of [How do I listen and spawn multiple child process in nodejs](http://stackoverflow.com/questions/32358845/how-do-i-listen-and-spawn-multiple-child-process-in-nodejs) – Paul Sweatte May 17 '17 at 21:47
  • 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. – coolaj86 May 19 '17 at 00:53
  • 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. – Julian Goacher Jun 12 '17 at 17:28

2 Answers2

0

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 &
coolaj86
  • 64,368
  • 14
  • 90
  • 108
-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();

thomasmeadows
  • 1,535
  • 7
  • 15