我对此感到很困惑,几个月来一直在努力寻找解决方案。我在OSX上。
我听说使用child_process.spawn并将detached选项设置为true,将启动子进程作为新进程组的领导者,如果父进程退出,子进程可能会继续运行。但是,我从未目睹过这方面的任何证据。
https://nodejs.org/api/child_process.html
例如:
const n = cp.spawn('node', ['watch-transpile.js'], {
detached: true,
stdio: ['ignore']
});
上述内容由父级执行,如果我们运行$ ps aux | grep node
我们得到:
Olegzandr 2546 0.0 0.2 3048544 19564 ?? Ss 11:29PM 0:00.09 node lib/transpile/watch-transpile.js
Olegzandr 2541 0.0 0.7 3115684 60216 s000 S+ 11:29PM 0:01.47 node index -t -a -w
但是当我用control-c杀死父级时,子进程和父进程一样死掉。
如何真正创建一个独立于具有节点的父进程的后台进程?这是杀了我!
答案 0 :(得分:2)
尝试使用child.unref()
方法。
默认情况下,父级将等待已分离的子级退出。至 防止父母等待给定的孩子,使用 child.unref()方法。这样做会导致父事件循环 不包括孩子的参考计数,允许父母 除非已建立IPC,否则独立于儿童退出 孩子和父母之间的渠道。
使用分离选项启动长时间运行的进程时, 父进程退出后,进程将不会在后台运行 除非它提供了未连接的stdio配置 到了父母。如果父母的stdio被继承,孩子将会继承 保持与控制终端的连接。
长时间运行的过程示例,通过分离并忽略它 父stdio文件描述符,以忽略父母的 终止:
示例:强>
const n = cp.spawn('node', ['watch-transpile.js'], {
detached: true,
stdio: ['ignore']
}).unref();
示例(来自文档):
const spawn = require('child_process').spawn;
const child = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: ['ignore']
});
child.unref();
或者,可以重定向子进程'输出到文件:
const fs = require('fs');
const spawn = require('child_process').spawn;
const out = fs.openSync('./out.log', 'a');
const err = fs.openSync('./out.log', 'a');
const child = spawn('prg', [], {
detached: true,
stdio: [ 'ignore', out, err ]
});
child.unref();
答案 1 :(得分:2)
啊哈!当然。那些愚蠢的Node文档!
这很有效。
const n = cp.spawn('node', ['lib/transpile/watch-transpile.js'], {
detached: true,
stdio: ['ignore', 'ignore', 'ignore']
});
您明确忽略了每个stdio流,而不仅仅是使用' ignore'一旦;文档没有直接提到这一点,但鉴于stdio属性是一个数组,它是有道理的。
在Github上查看此问题:https://github.com/nodejs/node/issues/7269#issuecomment-225698625