Всякий раз, когда вы используете такую конструкцию оболочки, как $ENV_VAR
, |
и т. Д., Убедитесь, что у вас действительно есть оболочка для их интерпретации, иначе у них будут свои буквальные значения! Чтобы понять, почему в вашем вызове отсутствует оболочка, вы должны понимать докер ENTRYPOINT
и CMD
.
Если вы посмотрите на файл Docker для ubuntu: последняя , вы увидите, что это
FROM scratch
И файл не устанавливает ENTRYPOINT
, только CMD
. Прочитайте В чем разница между CMD и ENTRYPOINT в Dockerfile? , чтобы получить отличную информацию о разнице. Достаточно сказать, что в вашем случае все после имени изображения заменяет cmd
.
Документ для containers.run()
говорит, что command
может быть str
или list
. Исходя из этого и из наблюдаемого поведения, мы можем сделать вывод, что командная строка будет разбита на пробелы, чтобы создать список аргументов для исполняющего устройства Docker.
Итак, ответ, короче говоря, заключается в том, что |
конструкция оболочки, но вы не выполняете оболочку. Есть несколько способов добавить оболочку в уравнение. Наиболее очевидным является прямой запуск оболочки:
>>> client.containers.run("ubuntu:latest", "bash -c 'echo hello world | wc'",)
' 1 2 12\n'
Но вы также можете установить точку входа в оболочку, что обычно делается в контейнерах общего назначения (хотя обратите внимание, что вы все равно должны убедиться, что -c
, и вся команда оболочки должна быть заключена в кавычки, как и раньше. Точка входа предоставляет только исполняемый файл, а не аргументы).
>>> 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")