为什么 SIGINT 可以在终端中停止 bash,但不能通过kill -INT 停止?

Fan*_*Lin 5 linux bash shell signals

我注意到当我通过这样的 bash 脚本运行挂起进程时

foo.sh:

sleep 999
Run Code Online (Sandbox Code Playgroud)

如果我通过命令运行它,然后按 Ctrl+C

./foo.sh
^C
Run Code Online (Sandbox Code Playgroud)

睡眠将被中断。但是,当我尝试用 SIGINT 杀死它时

ps aux | grep foo
kill -INT 12345  # the /bin/bash ./foo.sh process
Run Code Online (Sandbox Code Playgroud)

然后看起来 bash 和 sleep 忽略了 SIGINT 并继续运行。这让我很惊讶。我认为 Ctrl + C 实际上是向前台进程发送 SIGINT,那么为什么终端中的 Ctrl + C 和kill -INT 的行为不同呢?

nin*_*alj 6

CtrlC实际上发送SIGINT到前台进程bash(由一个进程和一个进程组成sleep)。要对命令执行相同的操作kill,请将信号发送到进程组,例如:

kill -INT -12345
Run Code Online (Sandbox Code Playgroud)


cod*_*eim 2

您的脚本正在执行“sleep 999”,当您按下 CTRL-C 时,运行 sleep 命令的 shell 会将 SIGINT 发送到其前台进程 sleep。但是,当您尝试使用kill从另一个窗口终止shell脚本时,您没有瞄准“睡眠”进程,而是瞄准了正在捕获SIGINT的父shell进程。相反,找到“sleep 999”的进程 ID 并杀死 -2 它,它应该退出。

简而言之,您正在测试用例中杀死 2 个不同的进程,并将苹果与橙子进行比较。

root     27979 27977  0 03:33 pts/0    00:00:00 -bash   <-- CTRL-C is interpreted by shell
root     28001 27999  0 03:33 pts/1    00:00:00 -bash
root     28078 27979  0 03:49 pts/0    00:00:00 /bin/bash ./foo.sh
root     28079 28078  0 03:49 pts/0    00:00:00 sleep 100  <-- this is what you should try killing
Run Code Online (Sandbox Code Playgroud)