哪些终端相关信号直接发送到 shell 的子进程,哪些信号通过 shell 进程间接发送?

哪些终端相关信号直接发送到 shell 的子进程,哪些信号通过 shell 进程间接发送?

如果我理解吉尔斯的回答是什么原因导致发送各种信号?正确的是,有几个与终端中运行的 shell 进程的作业控制相关的信号:

  • 按键通知:SIGINT、SIGQUIT、SIGTSTP

  • SIGSTOP、SIGCHLD、SIGCONT、

  • SIGTTIN 和 SIGTTOU

  • SIGWINCH 和 SIGHUP。

我想知道哪些终端相关信号是直接发送到shell的子进程而不先到达终端中的shell进程,哪些是先发送到终端中的shell进程并让shell重新发送到其子进程?

例如,对于最常用的两个信号,以下正确吗?

SIGHUP 首先发送到 shell 进程,然后将其重新发送到 shell 的所有子进程,无论它们是在前台还是后台(即何时nohup可以产生区别)。

当按 Ctrl-C 时,哪一项对于 SIGINT 是正确的:

  • 终端驱动程序仅向前台组中的进程发送 SIGINT,而不向终端中运行的父 shell 进程发送 SIGINT。因此父 shell 进程永远不需要处理 SIGINT。

  • 终端驱动程序将 SIGINT 发送到终端中运行的 shell 进程,shell 进程通过向前台组中的进程重新发送 SIGINT 来处理 SIGINT。

如果我理解 Stéphane Chazelas 的回复https://unix.stackexchange.com/a/384702/674正确,第一个正确吗?

谢谢!

答案1

当您在交互式 shell 中的前台运行作业时,只有该作业中的进程(相应的进程组中)才会收到 SIGINT(由内核而不是 shell 发送)^C

当不运行任何前台作业时,即在提示符下,当 shell 等待您输入命令行时,shell 位于前台。因此按^Cthen 会向 shell 发送一个 SIGINT 信号,shell 通常将其视为取消当前输入的文本;它还可以终止作为键或完成小部件的一部分调用的命令。您还可以在那里添加您自己的处理程序。


笔记

1 如果 shell 作为脚本的一部分启动,同时还并行运行一些其他命令,则其他进程可能位于同一进程组中。交互式 shell 将尝试在启动时为自己创建一个新的进程组(并使其成为前台进程组),但如果它们的进程已经是进程组领导者,则可能无法这样做。如果你这样做:

bash -c ': <(sleep 1000); exec bash'

然后Ctrl+C按该 shell 的提示bash,您会发现它sleep也会被杀死。

sleep像这样运行时你不会观察到它:

sh -c 'sleep 1000 & exec bash'

在这种情况下,sh显式忽略异步命令的 SIGINT sleep(在执行之前将 SIGINT 处置设置为 SIGIGN sleep)。

相关内容