Bash脚本如何响应SIGUSR信号且不传播至子进程?
解决方法:让子进程脱离父进程进程组
你的问题核心是父进程处理USR1/USR2信号时子进程意外终止,本质原因是子进程和父进程同属一个进程组,部分场景下信号会间接影响到子进程。要在父进程正常处理信号的同时保护子进程,可以通过让子进程脱离父进程的进程组来实现,具体有两种常用方式:
方式1:使用setsid启动子进程
setsid会让新进程成为新会话的领导者,彻底脱离原进程组,父进程收到的信号不会传递到子进程:
#!/usr/bin/env bash trap 'echo trapping && sleep inf' USR1 USR2 echo $$ # 用setsid启动gnome-calculator,使其脱离父进程组 setsid gnome-calculator &>/dev/null & sleep inf
方式2:使用nohup启动子进程
nohup不仅会忽略SIGHUP信号,还会让进程脱离终端关联,同样能避免父进程的信号影响子进程:
#!/usr/bin/env bash trap 'echo trapping && sleep inf' USR1 USR2 echo $$ # 用nohup启动gnome-calculator,同时重定向输出到/dev/null nohup gnome-calculator &>/dev/null & sleep inf
原理说明
默认情况下,后台运行的子进程会继承父进程的进程组。当父进程收到信号时,虽然信号本身只发给父进程,但部分GUI程序或依赖终端的进程可能会因父进程的状态变化(如原sleep命令被中断)间接终止。通过setsid或nohup让子进程独立成新的会话/进程组,就能彻底隔离父进程的信号影响,同时父进程仍能正常执行信号处理逻辑。
内容的提问来源于stack exchange,提问作者what the
相关产品推荐
相关产品推荐

