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

Docker容器捕获中断信号脚本配置问题咨询

问题分析与解决方案

首先,你遇到的信号监听不生效问题,核心原因是用/bin/bash -c包裹脚本作为ENTRYPOINT的方式,导致你的脚本不是容器的PID 1进程,信号被bash拦截了,没法传递给你的脚本。

为什么会这样?

当你设置ENTRYPOINT ["/bin/bash", "-c", "/application/scripts/cl.sh"]时,容器启动后,PID 1的进程是bash,而你的cl.sh是bash fork出来的子进程。在Linux系统中,只有PID 1进程会接收外部发送的信号(除非显式配置信号转发),而bash默认不会把信号转发给它的子进程。所以当你发送中断信号(比如9、137)时,bash会自己处理这些信号,你的脚本根本收不到,自然trap就不会触发。

另外还要提醒你:SIGKILL(信号9)是无法被进程捕获的,即使你的脚本成为PID 1,trap '...' 9也不会生效,因为内核会直接强制杀死进程,不给它处理信号的机会。信号137其实是进程被SIGKILL杀死后的退出码(128+9),同样没法被捕获,你可以改成监听SIGTERM(信号15)来测试,这个信号是可以被捕获的。

解决办法

你有两种方式可以让脚本正确接收信号:

方式1:直接将脚本作为ENTRYPOINT(推荐)

修改Dockerfile的ENTRYPOINT,直接指向你的脚本,同时确保脚本有可执行权限:

RUN apt-get update && [...]
WORKDIR "/application"
# 给脚本添加可执行权限
RUN chmod +x /application/scripts/cl.sh
# 直接用脚本作为ENTRYPOINT
ENTRYPOINT ["/application/scripts/cl.sh"]

方式2:用exec让脚本替换bash进程

如果因为某些原因必须用bash -c包裹,可以在脚本前加exec,让脚本取代bash进程成为PID 1:

RUN apt-get update && [...]
WORKDIR "/application"
ENTRYPOINT ["/bin/bash", "-c", "exec /application/scripts/cl.sh"]

是否需要重新构建容器?

是的!你修改了Dockerfile里的ENTRYPOINT配置,必须重新执行docker-compose build来构建新的镜像,然后用docker-compose up启动容器,新的配置才会生效。

测试建议

修改完后,你可以用以下命令测试信号监听:

  1. 启动容器后,找到容器ID:docker ps
  2. 发送SIGTERM信号测试:docker kill -s TERM <容器ID>
  3. 查看容器日志:docker logs <容器ID>,应该能看到你脚本里的退出提示。

内容的提问来源于stack exchange,提问作者Luigi T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:03:55