在 docker-py 中使用管道

Using pipes with docker-py

https://github.com/docker/docker-py 的示例中,它们 return 对 docker 图像的命令结果如下:

>>> client.containers.run("ubuntu:latest", "echo hello world")
'hello world\n'

我想要的是使用管道 - 例如,如果我可以这样做就太好了:

>>> client.containers.run("ubuntu:latest", "echo hello world | wc")
'       1       2      12\n'

然而,我得到的是:

 >>> client.containers.run("ubuntu:latest", "echo hello world | wc")
    b'hello world | wc\n'

在 docker 中 运行 两个命令的最简单方法是什么,第二个命令从第一个通过管道传输?

每当你使用 $ENV_VAR| 等 shell 结构时,请确保你确实有一个 shell 来解释它们,否则他们会他们的字面值!要了解为什么您的调用缺少 shell,您必须了解 docker ENTRYPOINTCMD

如果您查看 ubuntu:latest 的 docker 文件,您会发现它是

FROM scratch

并且文件没有设置 ENTRYPOINT,只有 CMD。阅读 What is the difference between CMD and ENTRYPOINT in a Dockerfile? 以获取有关差异的一些好看的信息。可以这么说,在您的情况下,图像名称之后的所有内容都替换了 cmd

containers.run() 的文档说 command 可以是 strlist。由此,以及从观察到的行为,我们可以推断命令字符串将按空格拆分,为 docker exec.

创建一个参数列表

所以,简而言之,答案是因为 | 是一个 shell 构造,但您没有执行任何 shell。有几种方法可以将 shell 添加到等式中。最明显的就是直接运行到shell:

>>> client.containers.run("ubuntu:latest", "bash -c 'echo hello world | wc'",)
'      1       2      12\n'

但您也可以将入口点设置为 shell,这通常在通用容器中完成(但请注意,您仍然必须确保提供 -c,并且整个 shell 命令必须像以前一样被引用。入口点只提供可执行文件,不提供任何参数)。

>>> client.containers.run("ubuntu:latest", "-c 'echo hello world | wc'", entrypoint="bash")
'      1       2      12\n'

命令行使用标准输入字段分隔符做同样的事情:

$ docker run --rm -it ubuntu:latest echo hello world \| wc
hello world | wc

如果我们引用整个内容,我们就会击败围绕输入字段分隔符的自动拆分:

$ docker run --rm -it ubuntu:latest "echo hello world \| wc"
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"echo hello world \\| wc\": executable file not found in $PATH": unknown.

python 等价于:

>>> client.containers.run("ubuntu:latest",["echo hello world \|"])
Traceback (most recent call last):
  [... traceback omitted for brevity ...]
docker.errors.APIError: 500 Server Error: Internal Server Error ("OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"echo hello world \\|\": executable file not found in $PATH": unknown")

简直就是:

client.containers.run("ubuntu:latest", "sh -c 'echo hello world | wc'")