2015-07-10 165 views
7

目前Docker存在问题;我使用它来运行启动时启动ipython笔记本的映像。我期望对ipython笔记本本身进行一些编辑,因此我需要在启动后关闭它。Docker未响应终端中的CTRL + C

但是,在终端中点击CTRL + C只需输入“^ C”作为字符串。似乎没有真正使用CTRL + C实际关闭ipython笔记本实例的方法。

有人会有什么线索可以导致这种情况,或知道任何解决方案吗?

回答

4

这篇文章提出CTRL-Z作为发送过程中的背景,然后通过它的进程ID杀死进程解决方法: Cannot kill Python script with Ctrl-C

可能出现的问题:

  • 程序捕获CTRL- c并且什么都不做,非常不可能。

  • 存在未正确管理的后台进程。只有主进程接收到信号并且子进程挂起。很可能发生了什么事情。

建议的解决方案:

  • 检查它如何正确地启动和停止的程序文件。 ctrl-c似乎不是正确的方法。

  • 用docker-entrypoint.sh bash脚本包装程序,该脚本阻止容器进程并能够捕获ctrl-c。这个bash示例应该有所帮助:https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash

  • 捕获ctrl-c后,为ipython笔记本调用正确的关闭方法。

0

@ maybeg的回答已经很好地解释了为什么会发生这种情况。

关于停止不响应的容器,另一种解决方案是在另一个终端中简单地发出docker stop <container-id>。与CTRL-C相反,docker stop不发送SIGINT而是SIGTERM信号,该进程可能对此作出不同反应。

用法:搬运工stop [选项]容器[容器...]

停止宽限期

如果失败后发送SIGTERM,然后SIGKILL运行的容器,使用docker kill <container-id>它立即发送一个SIGKILL。

+0

对于如何在docker中打包需要正确关闭例程的进程,您是否有最佳实践解决方案或入口点脚本? – blacklabelops

2

问题在于Ctrl-C向容器内的顶级进程发送一个信号,但该进程并不像您所期望的那样反应。顶级进程在容器内部具有ID 1,这意味着它不会获得进程通常具有的默认信号处理程序。如果顶层进程是一个shell,那么它可以通过自己的处理程序接收信号,但不会将其转发给在shell中执行的命令。细节解释here。在这两种情况下,Docker容器都会像忽略Ctrl-C一样。

如果您正在构建自己的映像,解决方案是运行一个最小的init进程,如tinidumb-init,作为容器中的顶级进程。