错误:无法启动容器:“stat /bin/sh: no such file or directory”

85

我一直在尝试创建自己的busybox基础镜像。

# ./mkimage.sh -t pensu/busybox busybox-static
+ mkdir -p /var/tmp/docker-mkimage.US3tHy0uBQ/rootfs
+ tar --numeric-owner -caf /var/tmp/docker-mkimage.US3tHy0uBQ/rootfs.tar.xz -C /var/tmp/docker-mkimage.US3tHy0uBQ/rootfs '--transform=s,^./,,' .
+ cat > '/var/tmp/docker-mkimage.US3tHy0uBQ/Dockerfile'
+ rm -rf /var/tmp/docker-mkimage.US3tHy0uBQ/rootfs
+ docker build -t pensu/busybox /var/tmp/docker-mkimage.US3tHy0uBQ
Sending build context to Docker daemon 863.2 kB
Sending build context to Docker daemon 
Step 0 : FROM scratch
 ---> 
Step 1 : ADD rootfs.tar.xz /
 ---> 8eac78bfc9d6
Removing intermediate container ad9bbb8f7536
Successfully built 8eac78bfc9d6
+ rm -rf /var/tmp/docker-mkimage.US3tHy0uBQ

我可以看到我的Docker仓库中有可用的镜像。
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
pensu/busybox       latest              8eac78bfc9d6        7 seconds ago       2.476 MB

但是当我尝试运行docker时,总是会出现错误:
# docker run -it pensu/busybox /bin/sh
exec: "/bin/sh": stat /bin/sh: no such file or directorytime="2015-04-09T16:03:45+05:30" level="fatal" msg="Error response from daemon: Cannot start container 8fe73b7832193c847d7975175a4be86d1f0b550b6a00b812bd4cdd18fe752468: exec: \"/bin/sh\": stat /bin/sh: no such file or directory" 

我不明白为什么会出现那个错误?我做错了什么吗?我还有哪些方法可以验证我创建的图像是否是正常工作的?


在我的情况下,是因为在shell文件中使用了错误的换行符。将其替换为Unix风格有所帮助。 - Dmitry Ivanov
在我的情况下,我没有指定WORKDIR,而且我使用了COPY . .命令,它使用了我的本地./bin来覆盖容器中的/bin目录。 - undefined
8个回答

88

创建图像后,使用以下命令进行检查:

$ docker inspect $image_name 

并检查您在CMD选项中拥有什么。对于忙碌的盒子,它应该是:

"Cmd": [
     "/bin/sh"
]

也许你在 ./mkimage.sh 中重写了 CMD 选项。


1
"Cmd": [ "/bin/sh", "-c", "#(nop) ADD file:905ed83e56295de9b6eb24708b583e78e4e9a06d3a80184276b55b5db04d70aa in /" ], 这里只是/bin/sh。 - Pensu
如果您想运行容器,必须提供容器执行的任务,现在Docker正在执行/bin/sh。例如,如果您想在容器内运行jar文件,请尝试使用java -jar yourjar.jar命令。 - wsl
这就是我正在思考的问题。使用busybox镜像无法获得交互式shell吗?在busybox容器中还能运行什么? - Pensu
1
@wsl,那个链接是关于在Docker中运行Java的。这个问题与Java无关。 - cowlinator
1
上面的注释说:“Cmd”:[“/ bin / sh”,“-c”,“#(nop)ADD file:905ed83e56295de9b6eb24708b583e78e4e9a06d3a80184276b55b5db04d70aa in /”] - 注意“ADD”内容; 您的Dockerfile中有一个拼写错误。 - tripleee
显示剩余3条评论

43

当我运行以下命令时,遇到了这个错误("stat /bin/bash: 没有那个文件或目录"):

docker exec -it 80372bc2c41e /bin/bash

解决方案是识别容器中可用的终端(或 shell)类型。为了做到这一点,我运行了以下命令:

docker inspect 80372bc2c41e

在那个命令的输出中,我看到了:

"Cmd": [
    "/bin/sh",
    "-c",
    "gunicorn -b 0.0.0.0:7082 server.app:app"
],

这告诉我可以使用/bin/sh命令,并且我能够连接:

docker exec -it 80372bc2c41e /bin/sh

3
CMD 部分如果出现 null 会怎样? - Reven
嗯,这应该意味着您的容器中没有运行任何命令。您有Dockerfile的链接吗? - duhaime

43

如果使用$ docker inspect [imageID]命令输出没有/bin/bash时,您可以使用下面的命令:

它对我非常有效。

$ docker exec -it <container id> sh

2
OCI运行时执行失败:执行失败:无法启动容器进程:exec:“sh”:在$PATH中找不到可执行文件:未知。 - pszaba

16

这个错误出现在从基础镜像(如scratch)创建Docker镜像时。这是因为生成的镜像没有可执行镜像的 shell。如果您使用:

docker run

命令而不是:

docker exec

命令,您需要在 Dockerfile 中添加以下内容:

ENV EXECUTABLE hello
cmd [$EXECUTABLE]

在您的 Docker 文件中,Docker 使用 /bin/sh 解析输入字符串,因此出现了错误。检查镜像,您会发现:

$docker inspect <image-name>
"Entrypoint": [
                "/bin/sh",
                "-c",
                "[$HM_APP]"
            ]

这意味着ENTRYPOINT或CMD参数将使用/bin/sh -c进行解析。对我有用的解决方案是将命令解析为字符串的JSON数组,例如:

这意味着ENTRYPOINT或CMD参数将使用/bin/sh -c进行解析。对我有用的解决方案是将命令解析为字符串的JSON数组,例如:

cmd ["hello"]

再次检查图像:

"Entrypoint": [
                "hello"
            ]

这将消除对/bin/sh的依赖,docker应用程序现在可以执行二进制文件。例如:

FROM scratch

# Environmental variables

# Copy files
ADD . /
# Home dir
WORKDIR /bin

EXPOSE 8083
ENTRYPOINT ["hospitalms"]

希望这能对未来的某个人有所帮助。


1
从 Docker 1.5.0 开始(具体来说是 docker/docker#8827),在 Dockerfile 中使用 FROM scratch 是无效的。使用 scratch “镜像” 表示构建过程中你希望 Dockerfile 中的下一个命令成为镜像中的第一层文件系统。这意味着你的容器不包含 /bin/sh 或其他任何东西(除了 Linux 内核)。 - cowlinator
是的,您没有内核附加到镜像上。运行任何Linux命令或依赖于docker shell的命令都将失败。 - MUNGAI NJOROGE

6
在使用Docker Toolbox/Machine的Windows (msys)上,我需要在/bin/bash前面添加一个额外的/来表示它是*nix文件路径。
因此,命令应该是: docker run --rm -it <image>:latest //bin/bash

真是个好小技巧啊。我之前不知道这个。 - joshmcode

5

使用命令 docker inspect image_name 来检查你的镜像 cmd ,输出结果可能如下:

"Cmd": [
    "/bin/bash",
    "-c",
    "#(nop) ",
    "CMD [\"/bin/bash\"]"
],

所以使用命令 docker exec -it container_id /bin/bash。如果您的cmd输出不同,例如:
"Cmd": [
    "/bin/sh",
    "-c",
    "#(nop) ",
    "CMD [\"/bin/sh\"]"
],

在上述命令中,使用/bin/sh代替/bin/bash


1
在Docker文件中明确提到你要运行的Ubuntu版本。
FROM ubuntu:14.04

不要使用类似 FROM ubuntu:Latest 这样的语句。这解决了我的上述"无法启动容器:stat /bin/sh: 没有那个文件或目录"问题。

1
我有一个类似的问题:

docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown.

在我的情况下,我知道图像在其他地方可以使用,所以是本地图像损坏了。我通过删除图像(docker rmi <imagename>)并重新拉取它(docker pull <imagename>)解决了这个问题。
我也执行了docker system prune,但我认为这不是必须的。

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