python - 通过 docker-py 使用管道
问题描述
在https://github.com/docker/docker-py的示例中,它们将命令的结果返回到 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,您必须了解 dockerENTRYPOINT
和CMD
.
如果您查看ubuntu:latest的 dockerfile ,您会发现它是
FROM scratch
而且该文件没有设置一个ENTRYPOINT
,只有一个CMD
。阅读Dockerfile 中的 CMD 和 ENTRYPOINT 有什么区别?有关差异的一些好看的信息。可以说,在您的情况下,图像名称之后的所有内容都替换了cmd
.
containers.run()
say的文档command
可以是 astr
或list
. 由此,以及观察到的行为,我们可以推断命令字符串将在空格上拆分,以创建 docker exec 的参数列表。
所以,简而言之,答案是因为|
它是一个 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")
推荐阅读
- objective-c - 在目标 c 中编码包含 ASCII 的字符串
- avrdude - avrdude:读取部分“ATmega4809”的签名数据时出错,rc=-67
- php - Symfony 路由来区分不明确的路径
- python - 如何在 Python 中搜索字符串的所有大写和小写版本?
- reactjs - 为 react redux 应用程序存储 API 密钥
- python - 如何计算循环函数的第一次重复?
- rx-java2 - 在自定义 RxJava 管道中实现背压
- c# - 加入两个列表并检查匹配的属性值并返回所需的数据
- python - 如何在 Python 中为家庭作业创建特定的维特比算法?
- postgresql - 使用 unix 域套接字从 docker 容器连接到 Postgresql 是不是很糟糕?