我有一个启动子进程的节点脚本。我希望确保在我的脚本终止时它们都被终止,无论它是否正常终止(应该没有剩下的子进程可以杀死)或者没有(这是我希望必须做的事情)。
我想过使用process.on('exit', fn)
,但我注意到forever(fn
)发起我的脚本时,forever myScript.js
未被调用。然而,当我正常运行我的脚本(node myScript.js
)时, 被调用。
我接着尝试找到一个我可以听到的信号,但以下似乎都没有被解雇:SIGUSR1
,SIGTERM
,SIGPIPE
,SIGHUP
, SIGTERM
,SIGINT
,SIGBREAK
,SIGWINCH
我也试过了process.on('beforeExit', ...)
,但也没有被解雇。
这是我用来测试这个的脚本(想象一下,不是记录一些文本,而是会杀死任何剩余的子进程):
myScript.js
console.log('started')
process.on('beforeExit', function () {
console.log('beforeExit fired')
})
process.on('exit', function () {
console.log('exit fired')
})
// signals
process.on('SIGUSR1', function () {
console.log('SIGUSR1 fired')
process.exit(1)
})
process.on('SIGTERM', function () {
console.log('SIGTERM fired')
process.exit(1)
})
process.on('SIGPIPE', function () {
console.log('SIGPIPE fired')
})
process.on('SIGHUP', function () {
console.log('SIGHUP fired')
process.exit(1)
})
process.on('SIGTERM', function () {
console.log('SIGTERM fired')
process.exit(1)
})
process.on('SIGINT', function () {
console.log('SIGINT fired')
process.exit(1)
})
process.on('SIGBREAK', function () {
console.log('SIGBREAK fired')
})
process.on('SIGWINCH', function () {
console.log('SIGWINCH fired')
})
// Let's keep the process open long enough to kill it manually
setTimeout(function () {}, 5000)
让我们通过启动脚本并在5秒钟之前用Ctrl-C
将其删除来试一试。首先“正常”:
$ node index.js
started
^CSIGINT fired
exit fired
$
这表现了我的预期。现在让我们永远尝试:
$ forever index.js
warn: --minUptime not set. Defaulting to: 1000ms
warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
started
^C
$
不同的行为。
答案 0 :(得分:2)
当您从命令行发送cntl-C时,forever
会获得一个SIGINT。你爆炸了forever
,而不是你的程序,所以我不一定希望你的程序运行它的exit
事件处理程序。
如果您将setTimeout
更改为炸毁程序(例如setTimeout(function () { undefined(); }, 500)
),那么您会看到exit
事件处理程序确实在运行。关键是代码行中引入的TypeError
(它试图像函数一样对待undefined
)会杀死你的程序,但不会永远杀死。
同样,如果您的程序正常退出,exit
事件也会触发,即使程序以forever
启动也是如此。
因此,只要process.on('exit');
本身未意外终止,即使您的程序由forever
启动和监控,我认为您也可以启用forever
。 (如果它意外终止,这只是一个问题。如果forever
优雅地停止你的程序,用forever stop
说,那就不会有问题。exit
事件将会触发。)< / p>