前台捕获SIGINT后,如何阻止后台子进程接收该信号?
解决后台子进程被Ctrl+C意外终止的问题
问题原因
当你在终端按下Ctrl+C时,终端会向当前前台进程组的所有进程发送SIGINT信号,而非只发给主shell。你的主shell虽然通过trap '' 2忽略了SIGINT,但后台运行的mpv进程和主shell属于同一个进程组,因此依然会收到SIGINT并终止。
解决方案
把mpv放到独立的进程组中,让它脱离主shell的进程组,这样终端的SIGINT就不会广播到它。最可靠的方式是用setsid命令启动mpv,它会创建一个新的会话和进程组,让mpv成为领头进程,彻底脱离原进程组的控制。
修改后的代码
function play_video_until_yes { trap '' 2 set -o ignoreeof videourl="$1" # 使用setsid让mpv在独立进程组运行 read -r mpv_pid < <(setsid mpv --loop "$videourl" --no-video &>/dev/null & echo $!) while true; do read -rp "Input y for yes: " answer if [[ "$answer" = "y" ]]; then break fi printf "\nIncorrect. Try again.\n" done kill "$mpv_pid" >/dev/null trap 2 set +o ignoreeof }
替代方案(若setsid不可用)
可以用子shell配合disown实现同样的效果,disown会把mpv从shell的作业列表中移除,同时让它脱离原进程组:
read -r mpv_pid < <( (mpv --loop "$videourl" --no-video &>/dev/null & echo $!; disown) )
内容的提问来源于stack exchange,提问作者Gigi Bayte 2
相关产品推荐
相关产品推荐

