如何在Docker容器中运行Bash?

306
我能在从docker/whalesay镜像创建的容器中运行任意的shell命令。
$ docker run docker/whalesay ls -l
total 56
-rw-r--r-- 1 root root  931 May 25  2015 ChangeLog
...

然而,我无法在从这个镜像创建的容器中运行bash
$ docker run docker/whalesay bash

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
7ce600cc9904        docker/whalesay     "bash"                   5 seconds ago       Exited (0) 3 seconds ago                           loving_mayer

为什么它没起作用?我该怎么让它起作用?

当您执行 docker exec -it 7ce600cc9904 /bin/bash 时会发生什么? - gaganso
2
@SilentMonk,它出现了这个错误:Error response from daemon: Container 7ce600cc990463518cc8fa073014942d99347b4ff0d6927031c8a839e8a8803e is not running - Lone Learner
1个回答

591

如果您运行docker run时没有附加tty,并且只调用bash,那么bash会找不到要执行的命令,然后退出。这是因为默认情况下容器是非交互式的,而在非交互模式下运行的shell需要运行脚本。如果没有脚本,它将退出。

要运行一个一次性的新容器,您可以简单地附加tty和标准输入:

docker run --rm -it --entrypoint bash <image-name-or-id>

或者为了防止上述容器被销毁,可以不使用--rm运行它。

或者,要进入正在运行的容器,请改用exec命令:

docker exec -it <container-name-or-id> bash

在评论中,您提出了一个问题

你知道这个命令和 docker run -it --entrypoint bash docker/whalesay 之间的区别吗?

在上面的两个命令中,您将 bash 指定为 CMD。而在这个命令中,您将 bash 指定为 ENTRYPOINT

每个容器都是使用 ENTRYPOINTCMD 的组合运行的。如果您(或镜像)没有指定 ENTRYPOINT,则默认的 entrypoint 是 /bin/sh -c

因此,在前面的两个命令中,如果您将 bash 作为 CMD 运行,且使用默认的 ENTRYPOINT,则容器将会使用:

/bin/sh -c bash

如果您指定--entrypoint bash,则会运行替代项。

bash <command>

其中<command>是图像中指定的CMD(如果有指定的话)。


4
谢谢。docker run -it docker/whalesay bash 是可以工作的。你知道这和 docker run -it --entrypoint bash docker/whalesay 有什么区别吗? - Lone Learner
1
为什么需要“-i”?据我了解,附加是默认的,那么 bash 的 stdin 不会保持打开状态吗? - Johannes Schaub - litb
当在PATH中找不到bash时,我该怎么办? - buhtz
1
如果您知道路径是什么,可以使用它,例如切换到/usr/local/bin/bash或其他路径。但也要记住,镜像可能没有bash,您应该尝试使用sh/bin/sh。这将取决于镜像的内容。 - Dan Lowe
当我只写<image-name-or-id>时,我如何知道这个“图像”具有什么属性? - buhtz
1
@buhtz 没有办法预测它。许多图像都有 bash;有些则没有,但可能会有 sh。甚至有一些图像根本没有 shell(例如,有单文件 Go 二进制图像就是这样)。 - Dan Lowe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接