You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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匹配子进程,存在以下问题:

  1. -f参数会匹配所有命令行包含signal_script的进程,可能误杀无关进程
  2. 如果子进程已经退出,pkill执行失败,导致主脚本无法被正确终止
  3. 若只终止子进程,主进程仍会在后台持续运行

修复方案

  1. 精准定位子进程:启动子进程时记录其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
}
  1. 跨终端终止主进程:直接用脚本启动时输出的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,提问作者Сергей Сергеев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:02:50