NodeJs在后台执行命令并忘记

Jac*_* M. 35 node.js

我有一个无尽的NodeJS script.js循环,我需要这个脚本在后台执行另一个脚本作为服务实际上是一个WebSocket服务.

var exec = require('child_process').exec;
exec('node bgService.js &');
Run Code Online (Sandbox Code Playgroud)

所以现在这两个脚本运行正常!

当我Ctrl+C对我进行操作时script.js,bgService.js脚本也会从内存中删除,我不想这样做.

如何在后台运行并忘记?

Leo*_*tny 54

您可以使用带有选项的child_process.spawn来执行此操作detached:

var spawn = require('child_process').spawn;
spawn('node', ['bgService.js'], {
    detached: true
});
Run Code Online (Sandbox Code Playgroud)

它将使子进程成为新进程组的领导者,因此在父进程退出后它将继续运行.

但是默认情况下,父进程会等待已分离的子进程退出,并且它也会监听它stdio.要将子进程与父进程完全分离,您应该:

  • 分离的孩子stdio从父过程中,管道的一些文件或/dev/null
  • 使用unref()方法从父事件循环引用计数中删除子进程

这是一个这样做的例子:

var spawn = require('child_process').spawn;
spawn('node', ['bgService.js'], {
    stdio: 'ignore', // piping all stdio to /dev/null
    detached: true
}).unref();
Run Code Online (Sandbox Code Playgroud)

如果您不想丢失子stdin输出,可以将其输出到某个日志文件:

var fs = require('fs'),
    spawn = require('child_process').spawn,
    out = fs.openSync('./out.log', 'a'),
    err = fs.openSync('./out.log', 'a');

spawn('node', ['bgService.js'], {
    stdio: [ 'ignore', out, err ], // piping stdout and stderr to out.log
    detached: true
}).unref();
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅child_process.spawn文档

  • @chovy是的,这就是主意.但请不要在非ES6问题中使用ES6语法,因为它可能会让人感到困惑. (2认同)

Bry*_*eld 5

简短回答:(tl;dr)

spawn('command', ['arg', ...],
  { stdio: 'ignore', detached: true }).unref()
Run Code Online (Sandbox Code Playgroud)

unref需要防止家长等待。

文档