如果我连接到docker容器
$> docker exec -it my_container zsh
在里面我想杀死我用ctrl+c
开始的东西我注意到它需要永远完成。我用Google搜索,似乎ctrl+c
的工作方式与您预期的有点不同。我的问题,如何在容器内修复ctrl+c
?
问题是Ctrl-C向容器内的顶级进程发送信号,但该进程不一定会像您期望的那样做出反应。顶级进程在容器内部具有ID 1,这意味着它不会获得进程通常具有的默认信号处理程序。如果顶级进程是shell,那么它可以通过自己的处理程序接收信号,但不会将其转发到shell中执行的命令。细节解释here。在这两种情况下,docker容器就好像它只是忽略Ctrl-C一样。
从docker 0.6.5
开始,您可以将-t
添加到docker run命令,该命令将附加pseudo-TTY
。然后,您可以键入Control-C
以从容器中分离而不会终止它。
如果你使用-t
和-i
,那么Control-C将终止容器。当使用-i with -t
时,你必须使用Control-P Control-Q
分离而不终止。
测试1:
$ ID=$(sudo docker run -t -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
Control-P Control-Q
$ sudo docker ps
容器仍然列出。
测试2:
$ ID=$(sudo docker run -t -i -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
Control-C
$ sudo docker ps
容器不存在(它已被终止)。如果在第二个示例中键入Control-P
Control-Q
而不是Control-C,则容器仍将运行。
使用docker-entrypoint.sh bash脚本包装程序,该脚本阻止容器进程并能够捕获ctrl-c。这个bash示例可能会有所帮助:https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash
#!/bin/bash
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
function ctrl_c() {
echo "** Trapped CTRL-C"
}
for i in `seq 1 5`; do
sleep 1
echo -n "."
done
使用Ctrl + \而不是Ctrl + C. 它杀死了这个过程而不是礼貌地要求它关闭。(阅读更多here。)
当我试图在docker容器中运行mdbook
(Rust可执行文件)时,我遇到了类似的问题。 mdbook
启动简单的网络服务器,我想通过Ctrl + C停止它,这是行不通的。
$ docker -ti --rm -p 4321:4321 my-docker-image mdbook serve --hostname 0.0.0.0 --port 4321
2019-08-16 14:00:11 [INFO] (mdbook::book): Book building has started
2019-08-16 14:00:11 [INFO] (mdbook::book): Running the html backend
2019-08-16 14:00:11 [INFO] (mdbook::cmd::serve): Serving on: http://0.0.0.0:4321
2019-08-16 14:00:11 [INFO] (ws): Listening for new connections on 0.0.0.0:3001.
2019-08-16 14:00:11 [INFO] (mdbook::cmd::watch): Listening for changes...
^C^C
受到@NID答案的启发,我通过通用bash脚本docker-entrypoint.sh
封装了mdbook可执行文件,它完成了这一操作(无需显式捕获INT信号)。
$ docker -ti --rm -p 4321:4321 my-docker-image docker-entrypoint.sh mdbook serve --hostname 0.0.0.0 --port 4321
2019-08-16 14:00:11 [INFO] (mdbook::book): Book building has started
2019-08-16 14:00:11 [INFO] (mdbook::book): Running the html backend
2019-08-16 14:00:11 [INFO] (mdbook::cmd::serve): Serving on: http://0.0.0.0:4321
2019-08-16 14:00:11 [INFO] (ws): Listening for new connections on 0.0.0.0:3001.
2019-08-16 14:00:11 [INFO] (mdbook::cmd::watch): Listening for changes...
^C $
docker-entrypoint.sh
的内容非常简单:
#!/bin/bash
$@