Fedora 37虚拟机中Bash脚本无法响应Ctrl-C/Ctrl-Z终止热键
问题分析与解决
问题1:Ctrl-C/Ctrl-Z被识别为普通输入
你的脚本中,SIGINT(对应Ctrl-C)和SIGTSTP(对应Ctrl-Z)的陷阱仅向子进程signal_script发送信号,但主脚本本身没有退出/暂停的逻辑。按下热键后,主脚本会继续执行循环,终端只是把Ctrl-C的转义序列^C显示出来,导致你误以为热键没被识别。
修复方案
修改陷阱处理逻辑,在发送信号给子进程后,添加主脚本的退出/暂停操作:
# Signal handling trap 'send_signal 2; exit 0' SIGINT # 发送信号后退出主脚本 trap 'send_signal 3; kill -STOP $$' SIGTSTP # 发送信号后暂停主脚本 trap 'send_signal 4; kill -CONT $$' SIGCONT # 发送信号后恢复主脚本
exit 0:收到SIGINT后,主脚本正常退出kill -STOP $$:暂停主进程(匹配Ctrl-Z的预期行为)kill -CONT $$:恢复主进程(匹配fg命令触发的SIGCONT)
问题2:跨终端终止脚本成功率低
当前用pkill -RTMIN+$signal -f $signal_script匹配子进程,存在以下问题:
-f参数会匹配所有命令行包含signal_script的进程,可能误杀无关进程- 如果子进程已经退出,
pkill执行失败,导致主脚本无法被正确终止 - 若只终止子进程,主进程仍会在后台持续运行
修复方案
- 精准定位子进程:启动子进程时记录其PID,避免模糊匹配:
# Start the signal script and record its PID bash "$signal_script" & signal_pid=$! # Update send_signal function send_signal() { signal=$1 if kill -0 "$signal_pid" 2>/dev/null; then # Check if child process is alive kill -RTMIN+$signal "$signal_pid" fi }
- 跨终端终止主进程:直接用脚本启动时输出的PID终止(比如示例中的9698):
kill <主进程PID> # 强制终止可执行 kill -9 <主进程PID>
若不知道PID,可精准匹配主脚本命令:
pkill -f "./time_logger"
额外优化建议
- 用
"$variable"包裹变量,避免文件名或路径含空格时出错(如bash "$signal_script"而非bash $signal_script) - 主脚本退出时自动终止子进程,避免产生孤儿进程:
trap 'send_signal 2; kill "$signal_pid" 2>/dev/null; exit 0' SIGINT
内容的提问来源于stack exchange,提问作者Сергей Сергеев
相关产品推荐
相关产品推荐

