捕捉 SIGTERM 与捕捉 SIGINT

Posted

技术标签:

【中文标题】捕捉 SIGTERM 与捕捉 SIGINT【英文标题】:Catching SIGTERM vs catching SIGINT 【发布时间】:2017-07-15 23:39:23 【问题描述】:

在 Node.js 服务器中,捕捉 SIGTERM 和捕捉 SIGINT 有什么区别吗?

我认为进程不应该能够防止在收到 SIGINT 时关闭?

  process.once('SIGINT', function (code) 
    console.log('SIGINT received...');
    server.close();
  );

 // vs.

  process.once('SIGTERM', function (code) 
    console.log('SIGTERM received...');
    server.close();
  );

我能否捕获两个信号并阻止退出?我的实验表明答案是肯定的,但根据我的阅读,SIGINT 总是假设关闭一个进程。

或者我把 SIGINT 和 SIGKILL 混淆了?也许 SIGKILL 是我无法恢复的信号?

捕获这些信号当然可以让我优雅地关机:

server.once('close', function()
    // do some other stuff
    process.exit(2); // or whatever code pertains
);

我认为我将 SIGINT 与 SIGKILL 混淆了 -

如果我尝试这样做:

 process.once('SIGKILL', function (code) 
    console.log('SIGKILL received...');
    exitCode = code || 2;
    server.close();
  );

我收到此错误:

 internal/process.js:206
        throw errnoException(err, 'uv_signal_start');
        ^
    Error: uv_signal_start EINVAL
        at exports._errnoException (util.js:1022:11)
        at process.<anonymous> (internal/process.js:206:15)
        at emitTwo (events.js:106:13)
        at process.emit (events.js:191:7)
        at _addListener (events.js:226:14)
        at process.addListener (events.js:275:10)
        at process.once (events.js:301:8)

所以显然你不能捕获 SIGKILL 信号,但你可以捕获 SIGINT 和 SIGTERM?

【问题讨论】:

【参考方案1】:

接受的答案是错误的。

    来自https://en.wikipedia.org/wiki/Unix_signal

SIGTERM SIGTERM 信号被发送到进程以请求其终止... SIGINT 几乎与 SIGTERM 相同。

    命令kill 周围的描述不正确。

您可以同时捕获它们,并且仍然可以使用 SIGKILL - kill -9 pid 关闭进程

错了。同样,来自上面的 wiki:

SIGKILL 信号被发送到进程以使其立即终止(终止)。与 SIGTERM 和 SIGINT 相比,这个信号不能被捕获或忽略,并且接收进程在接收到这个信号时不能执行任何清理。

总之,

SIGINT 几乎与 SIGTERM 相同

【讨论】:

我认为措辞有些混乱。 “您可以同时捕获它们(SIGINT 和 SIGTERM),并且仍然可以使用 SIGKILL - kill -9 pid 关闭进程”。这种说法是正确的。公认的答案是正确的。 我的意思是抓住其中任何一个(SIGINT 和 SIGTERM)与 SIGKILL 无关。 IE。您是否需要捕获其中任何一个(SIGINT 和 SIGTERM)才能使用SIGKILL - kill -9 pid 关闭进程才能工作? @蓝 嗯,是的,它们是三种不同的信号。您可以捕获 SIGINT 和 SIGTERM,然后做任何事情,仍然被 SIGKILL 杀死。您不必这样做,但 OP 要求澄清信号之间的差异。给定的场景就是这样。您可以忽略 SIGINT 和 SIGTERM,但不能忽略 SIGKILL。这里没有人真的错了,哈哈。 同意,但我认为OP有更好的总结,“你不能trap SIGKILL信号,但你可以trap SIGINT和SIGTERM?” 应该承认,而不是被模糊。 它们必须不同的原因是因为SIGTERM专门发生在程序应该终止的时候。 SIGINT 只是意味着用户按下了 ctrl+c,这有时意味着终止,但并非总是如此。例如,在 VIM 中,ctrl+c 可能是在编辑器中使用的实际命令,因此 SIGINT 仅用于告诉 VIM“哦,用户的意思是 ctrl+c”。或者,考虑 bash 本身。当你 ctrl+c,即给 bash 一个 SIGINT 时,bash 的工作是获取任何正在运行的进程,并给 that 程序 SIGINT(可能是任何程序)。如果你给 bash SIGTERM,它会死。【参考方案2】:

来自https://en.wikipedia.org/wiki/Unix_signal:

SIGINT由用户按Ctrl+C生成,是interrupt

SIGTERM 是发送来请求进程终止的信号。 kill 命令发送一个SIGTERM,它是一个terminate

您可以同时捕获SIGTERMSIGINT,并且始终可以使用SIGKILLkill -9 [pid] 关闭进程。

【讨论】:

以上是关于捕捉 SIGTERM 与捕捉 SIGINT的主要内容,如果未能解决你的问题,请参考以下文章

[linux] linux信号

shell信号捕捉命令 trap

shell脚本进阶之信号的捕捉

电路中signal path怎么看

Linux - 操作系统信号

python 信号通信