简体   繁体   English

通过 docker-py 使用管道

[英]Using pipes with docker-py

In the example at https://github.com/docker/docker-py , they return the results of a command to a docker image as so:https://github.com/docker/docker-py的示例中,它们将命令的结果返回到 docker 映像,如下所示:

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

What I want is to use a pipe - for instance, it would be great if I could do this:我想要的是使用 pipe - 例如,如果我能这样做会很棒:

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

However, instead I get this:但是,相反,我得到了这个:

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

What is the easiest way to run two commands, the second piped from the first, in docker?在 docker 中运行两个命令的最简单方法是什么?

Whenever you use a shell construct such as $ENV_VAR , |每当您使用 shell 构造,例如$ENV_VAR| , etc, make sure you actually have a shell to interpret them or they'll have their literal values, To see why your invocation lacks a shell, you have to understand docker ENTRYPOINT and CMD .等,确保您实际上有一个 shell 来解释它们,否则它们将具有它们的字面值,要了解您的调用为什么缺少外壳,您必须了解 docker ENTRYPOINTCMD

If you look at the dockerfile for ubuntu:latest ,you'll see that it is如果您查看ubuntu:latest的 dockerfile,您会发现它是

FROM scratch

And the file doesn't set an ENTRYPOINT , only a CMD .而且该文件没有设置ENTRYPOINT ,只有CMD Read What is the difference between CMD and ENTRYPOINT in a Dockerfile?阅读CMD 和 Dockerfile 中的 ENTRYPOINT 有什么区别? for some good looking info about the difference.有关差异的一些好看的信息。 Suffice it to say that in your case everything after the image name replaces the cmd .可以说,在您的情况下,图像名称之后的所有内容都替换了cmd

The doc for containers.run() says command can be a str or list . containers.run()的文档说command可以是strlist From that, and from observed behavior, we can infer the command string will be split on whitespace to create a list of arguments for the docker exec.由此,根据观察到的行为,我们可以推断命令字符串将在空白处拆分,以创建 arguments 列表,用于 docker exec。

So, the answer, in short, is because |所以,简而言之,答案是因为| is a shell construct but you're executing no shell.是 shell 构造,但您没有执行 shell。 There's a few ways to add a shell into the equation.有几种方法可以将 shell 添加到等式中。 The most obvious is to run the shell directly:最明显的是直接运行shell:

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

But you could also set the entrypoint to a shell, which is commonly done in general purpose containers (though notice you still have to make sure that -c is provided, and the entire shell command must be enquoted as before. The entrypoint only provides the executable, not any arguments).但是您也可以将入口点设置为 shell,这通常在通用容器中完成(但请注意,您仍然必须确保提供-c ,并且必须像以前一样引用整个 shell 命令。入口点仅提供可执行文件,而不是任何参数)。

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

The command line does the same thing with the standard input field separator:命令行使用标准输入字段分隔符执行相同的操作:

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

If we enquote the whole thing we defeat the automatic splitting around the input field separator:如果我们引用整个内容,我们会破坏输入字段分隔符周围的自动拆分:

$ 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.

The python equivalent is: 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")

It is simply:很简单:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM