linux - 为什么父 bash 等待子 bash 死亡才执行 trap

标签 linux bash shell pid kill

假设我有一个 shell 和另一个外部 shell。 在第一个 shell 上,我运行 bash:这是父 bash。例如,在父 bash 中,我使用 trap exit INT 设置了一个陷阱。 然后我在这个父bash中再次运行bash,所以我得到了一个子bash,我可以在其中做任何事情。 然后,从外部 shell 中,如果我尝试使用 -INT 标志杀死父 bash 的 PID,它不会执行任何操作。一旦我退出子 bash,它就会返回到父 bash 并执行陷阱并立即杀死父 bash。

我的主要问题是如何强制立即执行陷阱,即使相应的 bash 打开了一些子 shell?我该如何解决这个问题? 我不希望像 -9 这样残酷的执行,因为我仍然希望 bash 的陷阱执行特定的清理工作。

INT 似乎并不重要。 示例:在一个 shell 中运行:

bash
ps
trap "echo HELLO" TERM
bash

在另一个 shell 中写入:

kill -TERM (pid that you read in ps)

在您实际退出子 bash 之前它不会执行任何操作

最佳答案

您遇到了 shell 对键盘中断(SIGINT 和 SIGQUIT)所做的特殊处理。这些信号由终端发送到整个进程组,但通常应该只终止组中的“前台”进程。

其实际工作方式是,当 shell(任何 shell,不仅仅是 bash)调用子进程(任何子进程、shell 或可执行文件或其他)并立即等待子进程完成(shell 中的前台命令)时,在等待时,它会忽略 SIGINT(和 SIGQUIT)信号。一旦子进程完成(这可能是由于子进程从键盘的 SIGINT 信号退出),shell 再次变为前台并且不再忽略 SIGINT/SIGQUIT。

由此得出的结论是,您不应将键盘控制信号用于键盘控制操作以外的其他用途。如果您想要终止父 shell,无论其状态如何,请使用 SIGTERM 信号。这就是 TERM 信号的用途。

关于linux - 为什么父 bash 等待子 bash 死亡才执行 trap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48232265/

相关文章:

linux - 如何使用不同的端口在同一 IP 上运行多个 Web 应用程序

linux - 如何根据条件使用 grep 删除行?

json - 使用 json 数组 curl

Bash:选择与模式匹配的上一个命令

linux - 通过配对 linux 中的值将 2 个文件的内容复制到新文件中

ruby-on-rails - 使用用户传递的参数作为服务器端执行的 shell 命令的一部分是否危险

c++ - 调用 fork() 后 SSL_accept 挂起

c - printk 格式中 %pa[p] 中 p 的含义

linux - Makefile 中的源环境变量文件

linux - 更改目录中具有 csv 扩展名的文件名