如何在docker容器中修复ctrl + c

问题描述 投票:11回答:2

如果我连接到docker容器

$> docker exec -it my_container zsh

在里面我想杀死我用ctrl+c开始的东西我注意到它需要永远完成。我用Google搜索,似乎ctrl+c的工作方式与您预期的有点不同。我的问题,如何在容器内修复ctrl+c

shell docker kill-process
2个回答
18
投票

问题是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

4
投票

使用Ctrl + \而不是Ctrl + C. 它杀死了这个过程而不是礼貌地要求它关闭。(阅读更多here。)


1
投票

当我试图在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

$@
© www.soinside.com 2019 - 2024. All rights reserved.