当进入子 shell 时,未被忽略的陷阱应设置为默认操作
来源:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_28
显然,对于我从 shell 调用的外部程序来说也是如此。trap "" SIGNAL
致力于捕获(忽略)该信号。但trap action SIGNAL
不调用action
,不执行任何操作,并且信号处理似乎设置为其原始默认值。
这种行为是在哪里定义的?
答案1
trap
signal()
是 shell 的内置函数,为/提供接口sigaction()
。在这方面,外部命令的行为与更改信号配置的其他语言中的行为相同。
当您通过execve()
系统调用执行另一个命令时,进程的内存(包括代码)(包括信号处理程序的代码)将被擦除,并被新的可执行文件的代码替换,因此信号处理程序无法生存。
在调用过程映像中设置为默认操作 (
SIG_DFL
) 的信号应在新过程映像中设置为默认操作。除 之外SIGCHLD
,被调用过程映像设置为忽略 (SIG_IGN
) 的信号应被新过程映像设置为忽略。设置为由调用过程映像捕获的信号应设置为新过程映像中的默认操作(看<signal.h>
)。如果
SIGCHLD
信号被设置为被调用过程映像忽略,则未指定该SIGCHLD
信号是被设置为被忽略还是被设置为新过程映像中的默认操作。
trap '' NAL
设置SIG_IGN
信号 和 的处置trap - NAL
SIG_DFL
。
trap
有额外的要求(其中许多可以被视为限制并且某些 shell 实现会忽略):
- 虽然进程在分叉时继承信号处理程序,但在 shell 中,处理程序在子 shell 中重置。对于某些信号,这很有用,例如经常发送给父级和子级的 SIGINT/SIGQUIT/SIGHUP/SIGTSTP,有时则不会。
- POSIX shell 禁止允许用户恢复启动时被忽略的信号处理程序。
- 异步命令中的某些信号会被自动忽略。
- 与 SIGCHLD 混合通常不起作用,因为 shell 会自行处理它。
- 我总是发现 shell 脚本中的信号处理通常不可靠且不可移植。