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

为什么使用source执行bash脚本时SIGINT陷阱无法生效

问题原因解释

两种执行方式的核心差异是脚本运行的进程上下文不同,具体逻辑如下:

1. bash script.sh/./script.sh执行时trap生效的原因

  • 这两种执行方式都会启动一个独立的非交互式bash子进程来运行整个脚本
  • 按下Ctrl+C发送的SIGINT信号会直接递交给这个子进程
  • 子进程内提前注册的trap规则匹配到SIGINT,就会触发no_ctrlc函数执行,函数内的exit会终止当前子进程,回到父级交互式shell,符合预期表现。

2. source script.sh执行时trap不生效的原因

  • source是在当前正在使用的交互式bash进程内逐行执行脚本内容,不会创建新的子进程,trap规则实际是注册在你当前用的终端shell上
  • 你观察到的无响应现象和sleep 5这个外部命令的执行逻辑直接相关:
    • 交互式bash运行外部命令时,会暂时将前台进程组权限交给sleep进程,自身退到后台等待外部命令执行结束
    • 按下Ctrl+C时,SIGINT只会发送给当前前台进程组的sleep进程,sleep收到信号后直接终止退出,退出码为130
    • 交互式bash收回前台控制权后,会默认忽略本次伴随前台命令终止产生的SIGINT(这是交互式shell的默认设计:如果每次打断前台命令都触发shell自身的trap,那你日常打断ping/grep等命令时都可能触发shell的自定义规则甚至直接退出终端,完全不符合使用预期)
    • 外层while true判断条件始终为真,会直接进入下一轮循环,因此你会看到Ctrl+C仅打断了当前的sleep,trap函数完全不会触发,看起来就像Ctrl+C失效了。

补充验证:你可以把脚本内的sleep 5替换成内置命令:(空操作)再执行source script.sh,此时按下Ctrl+C会直接触发trap函数,甚至会因为exit直接退出当前终端,就是因为此时没有前台外部命令,bash自身会处理收到的SIGINT信号。

内容的提问来源于stack exchange,提问作者Limone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:15:09