防止信号传递给子进程(NodeJS)

4

I have NodeJS code like the following:

[myFile.js]

var path  = require("path");
var cp  = require("child_process");
var child = cp.spawn( "python",["HelloWorld.py"], { stdio:'pipe', });

child.stdout.on('data', (data) => {
    console.log(`CHILD stdout: ${data }`);
});

child.stderr.on('data', (data) => {
  console.log(`CHILD stderr: ${data}`);
});

process.on("SIGINT",()=>{
    // close gracefully
    console.log("Received SIGINT");
})
child.on('exit',(code)=>{console.log(`child Process exited with code ${code}`)})

并且像Python脚本这样:

[HelloWorld.py]

print 'Hi there'
import time
time.sleep(5)

我希望能够优雅地管理关机,但是当我通过命令行启动这段代码时:

> node myFile.js

当我按下control-C时,这个被打印到控制台上:
^CReceived SIGINT
CHILD stdout: Hi there

CHILD stderr: Traceback (most recent call last):
  File "HelloWorld.py", line 3, in <module>
    time.sleep(5)
KeyboardInterrupt

child Process exited with code 1

这段文本表明Python(在子进程中运行)接收了“^C”键盘事件。但是,我更喜欢子进程比在键盘中断时崩溃更加优雅地退出。

我尝试了各种组合 options.stdio 的设置,包括 [undefined,'pipe','pipe'] (不起作用),['ignore','pipe','pipe'] (导致子进程崩溃),而且我试过使用 worker.stdin.end() (也导致子进程崩溃)。

有没有办法继承父NodeJS进程的标准输入?


你是否反对在Python脚本中捕获异常?如果不是,你可以将其包装在try catch语句中以消除错误。参见:https://dev59.com/cmw05IYBdhLWcg3wuUAL - Mike
1
好的观点,但我的问题是关于NodeJS,不是Python。我在上面的示例中使用Python是因为(A)它清楚地表明KeyboardInterrupt正在传递给子进程,以及(B)我编写的代码是用于通用任务运行器,并且无法在每个将在子进程中运行的脚本和语言中注入try/catch -- 最好防止首先将中断发送到子进程。 - Jthorpe
1个回答

6

RTFM:将 options.detached 设置为true可以防止传播杀死信号,这就是附加的子进程在父进程被杀死时如何被杀死的惊喜...


5
将以下与编程有关的内容从英语翻译成中文。仅返回翻译后的文本:(如果您因嘲讽而投反对票,请意识到我正在回答自己的问题...) - Jthorpe
我承认我给它投了反对票。我没有意识到你是在回答自己,对此感到抱歉。我可以取消反对票,但你需要编辑你的回答。 - RoyalBingBong
2
还值得一提的是,在终端中的 ^C 命令会向整个进程组发送 SIGINT 信号。如果您手动kill主进程,则应该能够在不需要将子进程分离的情况下优雅地停止它们。类似的事情也会发生在systemd.service中,但您可以设置KillMode - RoyalBingBong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接