Bash在HereDoc与交互模式下的SIGINT信号处理差异疑问
区分HereDoc与交互模式下SIGINT行为的核心原因
核心在于信号处理的重置和前台进程组的信号递送规则,并非你以为的“共享信号处理程序”导致的矛盾:
子进程的信号处理会被Shell主动重置
交互Shell启动时,会把SIGINT的处理设置为自定义逻辑(比如收到Ctrl+C时只清空当前输入、刷新提示符,不会终止自身)。但当Shell fork出cat这类子进程来处理HereDoc时,会在子进程执行exec之前,将SIGINT、SIGQUIT这类信号的处理恢复为系统默认值。也就是说,cat进程的SIGINT处理是“收到即终止”,和Shell的处理逻辑完全独立——子进程继承的是信号处理的副本,Shell会主动修改这个副本,不存在真正的“共享”。前台进程组决定信号的接收对象
终端发送的SIGINT只会递送给当前前台进程组的所有进程:- 交互模式下,Shell自身是前台进程组的领头进程,收到SIGINT后触发自定义处理,只会中断当前输入流程,不会终止Shell;
- 执行
cat <<eof进入交互输入HereDoc时,cat会被切换到前台进程组,Shell则进入后台等待。此时按Ctrl+C,SIGINT只会发送给前台的cat进程,触发它的默认终止行为,Shell根本不会收到这个信号。
简单说,两种场景下接收SIGINT的进程不同,且它们的信号处理逻辑被Shell刻意区分开了,所以行为完全不一样。
内容的提问来源于stack exchange,提问作者Rache Bartmoss
相关产品推荐
相关产品推荐

