无法捕获来自“docker停止”的TERM信号

这是我在CMD中使用的bash脚本

#!/bin/bash set -eo pipefail echo "Setting trap" echo $$ echo $BASHPID trap 'cleanup' TERM trap 'cleanup' KILL cleanup() { echo "Cleaning up..." kill -TERM `jobs -p` } # To start the essential services service ntp start service awslogs start cd /app python -m job_manager & wait 

Docker文件不是很有趣

 FROM ubuntu:16.04 RUN apt-get update --fix-missing && apt-get install -y \ git \ python \ python-pip \ ntp \ curl ENV APP_HOME /app RUN mkdir -p ${APP_HOME} COPY src/ ${APP_HOME}/ # job-cmd.sh is kept here COPY docker/helper-files/* / CMD /job-cmd.sh 

这个想法是捕获job-cmd.sh中的TERM信号,然后传递给python任务。

我已经尝试了一些时间,并没有工作。 我添加这些电话后

 echo $$ echo $BASHPID 

我意识到CMD过程的PID实际上是7而不是我所期望的。

我的问题:

1)为什么bash进程分配PID 7?

2)我如何修复我的作业脚本/ dockerfile?

我认为这是因为你正在使用CMD指令的shellforms。 从https://docs.docker.com/engine/reference/builder/#cmd

如果你想在没有shell的情况下运行你的命令,那么你必须把这个命令表示为一个JSON数组,并给出可执行文件的完整path。 这个数组forms是CMD的首选格式。

所以,用Dockerfilereplace你的CMD指令:

 CMD ["/job-cmd.sh"] 

然后你的Bash进程将被分配PID 1 。 您的TERM处理程序将正常工作,但您无法捕获KILL信号。 从man trap

捕获SIGKILL或SIGSTOP在某些历史实现中在语法上被接受,但是它没有效果。 便携式POSIX应用程序不能试图捕获这些信号。

仅供参考,我在这里解释更多关于PID 1问题: https : //serverfault.com/questions/869543/bash-script-entrypoint-pid-1-kills-tail-sub-process-only-if-a-fake-陷阱WHI / 870872#870872