Search code examples
javascriptnode.jsterminalspawnchild-process

How to replace node.js process with spawned child?


I am building a node.js application and packaging it as a binary (using nexe) and want to update and restart the process if an update is available. When I spawn the new process and exit, I want the new process to take over the terminal but that is not happening. Here's what I am doing (using child_process):

var spawn = require('child_process').spawn;
var child = spawn(process.execPath, process.argv, {
  cwd: process.cwd(),
  env: process.env,
  detached: true,
  stdio: 'inherit'
});
child.unref();
process.exit();

The child process prints all its console logs on the terminal but goes into the background. Where am I going wrong? I am using OS X Mavericks.


Solution

  • You can do something like this:

    When you start the application, start it via another script. This will spawn the child process and kill it as needed.

    mother.js

    var child;
    var spawn = require('child_process').spawn;
    var argv =  process.argv;
    argv.shift();
    argv.shift();
    
    function startChild(){
      console.log("STARTING", process.execPath, "child.js", argv);
      child = spawn(process.execPath,  ["child.js", argv], {
        cwd: process.cwd(),
        env: process.env,
        detached: true
      });
      child.on('error', function(e){console.log(e)});
      child.stdout.pipe(process.stdout);
      console.log("STARTED with PID:", child.pid);
    }
    
    
    process.on('SIGQUIT', function() {
      child.kill();
      startChild();
    });
    startChild();
    

    child.js

    (function(){
      console.log("Started child process");
      setInterval(function(){console.log("running")}, 1000);
    })();
    

    You can then send ctrl+c to kill the thing. To reload send ctrl+\ or invoke in mother.js from your update function.