[英]Docker bash shell script does not catch SIGINT or SIGTERM
我在一个目录中有以下两个文件:
Dockerfile
FROM debian
WORKDIR /app
COPY start.sh /app/
CMD ["/app/start.sh"]
start.sh
(权限 755 使用chmod +x start.sh
)
#!/bin/bash
trap "echo SIGINT; exit" SIGINT
trap "echo SIGTERM; exit" SIGTERM
echo Starting script
sleep 100000
然后我运行以下命令:
$ docker build . -t tmp
$ docker run --name tmp tmp
然后我希望按 Ctrl+C 会向程序发送一个 SIGINT,程序会将 SIGINT 打印到屏幕然后退出,但这并没有发生。
我还尝试运行$ docker stop tmp
,我希望它会向程序发送一个 SIGTERM,但检查$ docker logs tmp
后显示没有捕获到 SIGTERM。
为什么 SIGINT 和 SIGTERM 没有被 bash 脚本捕获?
CTRL+C 向在该控制台上运行的docker
发送信号。
向您可以使用的脚本发送信号
docker exec -it <containerId> /bin/sh -c "pkill -INT -f 'start\.sh'"
或者在脚本中包含echo "my PID: $$"
并发送
docker exec -it <containerId> /bin/sh -c "kill -INT <script pid>"
docker 中的某些 shell 实现可能会忽略该信号。 此脚本将正确响应pkill -15
。 请注意,指定的信号没有SIG
前缀。
#!/bin/sh
trap "touch SIGINT.tmp; ls -l; exit" INT TERM
trap "echo 'really exiting'; exit" EXIT
echo Starting script
while true; do sleep 1; done
由于sleep
可能会忽略某些信号,因此 long sleep
命令被一个无限循环的短命令取代。
实际上,如果您使用以下命令之一运行容器,您的Dockerfile
和start.sh
入口点脚本对我来说就像Ctrl+C一样工作:
docker run --name tmp -it tmp
docker run --rm -it tmp
--interactive
= -i
CLI 标志要求即使没有连接也保持 STDIN 打开--detach
= -d
CLI 标志时)--tty
= -t
CLI 标志要求分配一个伪 TTY为了完整起见,请注意有几个相关问题可能会使docker stop
花费太多时间并“退回”到docker kill
,这可能在 shell 入口点启动其他一些进程时出现:
exec
内置命令:exec prog arg1 arg2 ...
INT
/ TERM
,但不是KILL
)非常重要;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.