the*_*can 15 bash shell sigint sigterm docker
我的目录中有以下两个文件:
Dockerfile
FROM debian
WORKDIR /app
COPY start.sh /app/
CMD ["/app/start.sh"]
Run Code Online (Sandbox Code Playgroud)
start.sh
(使用权限 755 chmod +x start.sh
)
FROM debian
WORKDIR /app
COPY start.sh /app/
CMD ["/app/start.sh"]
Run Code Online (Sandbox Code Playgroud)
然后我运行以下命令:
$ docker build . -t tmp
$ docker run --name tmp tmp
Run Code Online (Sandbox Code Playgroud)
然后我期望按 Ctrl+C 会向程序发送 SIGINT,该程序会将 SIGINT 打印到屏幕然后退出,但这并没有发生。
我还尝试运行$ docker stop tmp
,我希望它会向程序发送一个 SIGTERM ,但$ docker logs tmp
之后检查显示 SIGTERM 未被捕获。
为什么 bash 脚本没有捕获 SIGINT 和 SIGTERM?
实际上,只要您使用以下命令之一运行容器,您Dockerfile
的start.sh
入口点脚本就可以像我一样工作:Ctrl+C
docker run --name tmp -it tmp
docker run --rm -it tmp
--interactive
= CLI标志-i
要求保持 STDIN 打开,即使未附加--detach
= -d
CLI 标志时)--tty
= CLI标志-t
要求分配一个伪 TTY为了完整起见,请注意,有几个相关问题可能会花费docker stop
太多时间并“回退”到docker kill
,当 shell 入口点启动其他进程时可能会出现这种情况:
exec
内置命令:exec prog arg1 arg2 ...
INT
/ TERM
,但不是 KILL
)非常重要;CTRL+C 发送信号以docker
在该控制台上运行。
要向脚本发送信号,您可以使用
docker exec -it <containerId> /bin/sh -c "pkill -INT -f 'start\.sh'"
Run Code Online (Sandbox Code Playgroud)
或者包含echo "my PID: $$"
在您的脚本中并发送
docker exec -it <containerId> /bin/sh -c "kill -INT <script pid>"
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
长sleep
命令被短命令的无限循环所取代,因为sleep
可能会忽略一些信号。
归档时间: |
|
查看次数: |
10794 次 |
最近记录: |