Docker:可以将 cmdline 参数附加到 shell 内置命令参数中吗?
我想创建一个带有 cmdline 可指定退出代码的 docker 映像。 从这个问题中,我了解到我必须使用 exit
作为 sh
的参数,因为它是 shell 内置命令,而不是可执行文件:如何使 docker 容器退出特定的错误代码docker-compose?
即,我可以创建一个以错误代码 42 退出的 docker 容器,如下所示:
# Dockerfile
FROM alpine:3.15 as base
ENTRYPOINT ["sh", "-c", "exit 42"]
$ docker build -t tmp:tmp . && docker run tmp:tmp
[+] Building 0.4s (5/5) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 181B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/alpine:3.15 0.0s
=> CACHED [1/1] FROM docker.io/library/alpine:3.15 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:3034115e85f4ac9322c3e3e5d69f4445e30cc652f3b836d0145545305fda6ad1 0.0s
=> => naming to docker.io/library/tmp:tmp 0.0s
$ echo $?
42
$
问题:
可以让 docker 容器返回指定为 cmdline 参数的退出代码吗?
例如,这可能吗:
$ docker build -t tmp:tmp . && docker run tmp:tmp 64
...
$ echo $?
64
$
?
我尝试过的:
本文 -- https://goinbigdata.com/docker-run-vs -cmd-vs-entrypoint/ - 让我尝试了 ENTRYPOINT
和 CMD
的组合:
# Dockerfile
FROM alpine:3.15 as base
ENTRYPOINT ["sh", "-c", "exit"]
CMD ["0"]
$ docker build -t tmp:tmp . && docker run tmp:tmp 64
...
$ echo $?
0
有趣的是,Dockerfile 的这种“模式”适用于echo
:
# Dockerfile
FROM alpine:3.15 as base
ENTRYPOINT ["echo", "hello"]
CMD ["world"]
$ docker build -t tmp:tmp . && docker run tmp:tmp
...
hello world
$
$ docker build -t tmp:tmp . && docker run tmp:tmp foo
...
hello foo
$
我认为我对 ENTRYPOINT
和 CMD
的失败实验可以通过这个实验来解释:
$ sh -c "exit 42"
$ echo $?
42
$ sh -c "exit" 42
$ echo $?
0
...我希望我的 Dockerfile 与 ENTRYPOINT ["sh", "-c", "exit"]
和 CMD ["0"]
会导致前者,但我认为它会导致后者 - true ?
I want to create a docker image with a cmdline-specifiable exit code.
From this question, I learned that I must use exit
as an argument to sh
because it is a shell built-in command, not an executable: How to make a docker container exit with a specific error-code with docker-compose?
I.e. I can create a docker container that exits with error-code 42 as follows:
# Dockerfile
FROM alpine:3.15 as base
ENTRYPOINT ["sh", "-c", "exit 42"]
$ docker build -t tmp:tmp . && docker run tmp:tmp
[+] Building 0.4s (5/5) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 181B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/alpine:3.15 0.0s
=> CACHED [1/1] FROM docker.io/library/alpine:3.15 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:3034115e85f4ac9322c3e3e5d69f4445e30cc652f3b836d0145545305fda6ad1 0.0s
=> => naming to docker.io/library/tmp:tmp 0.0s
$ echo $?
42
$
Question:
Can the docker container be made to return an exit-code specified as a cmdline argument?
E.g. is this possible:
$ docker build -t tmp:tmp . && docker run tmp:tmp 64
...
$ echo $?
64
$
?
What I've tried:
This article -- https://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/ -- led me to try this combination of ENTRYPOINT
and CMD
:
# Dockerfile
FROM alpine:3.15 as base
ENTRYPOINT ["sh", "-c", "exit"]
CMD ["0"]
$ docker build -t tmp:tmp . && docker run tmp:tmp 64
...
$ echo $?
0
Interestingly, this same "pattern" of Dockerfile worked for echo
:
# Dockerfile
FROM alpine:3.15 as base
ENTRYPOINT ["echo", "hello"]
CMD ["world"]
$ docker build -t tmp:tmp . && docker run tmp:tmp
...
hello world
$
$ docker build -t tmp:tmp . && docker run tmp:tmp foo
...
hello foo
$
I think my failed experiment with ENTRYPOINT
and CMD
is explained by this experiment:
$ sh -c "exit 42"
$ echo $?
42
$ sh -c "exit" 42
$ echo $?
0
...I hoped that my Dockerfile with ENTRYPOINT ["sh", "-c", "exit"]
and CMD ["0"]
would result in the former, but I think it results in the latter -- true?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您定义了一个,则所有 docker run 参数都将传递到您的
entrypoint.sh
。例如,在我的 Dockerfile 中,我有:
在我的 entrypoint.sh 中
,然后使用 args 运行:
All your docker run arguments are being passed to your
entrypoint.sh
if you have one defined.For example in my Dockerfile I have:
And in my entrypoint.sh
And then just run with args:
你是对的,
CMD
总是将其内容作为新参数传递给入口点。您不能将其作为ENTRYPOINT
参数的一部分插入。我还推荐 Florin 的解决方案,即拥有一个自定义入口点。但是,如果您确实需要,您仍然可以仅使用 shell 来执行此操作:
这将使用 4 个参数运行
sh
,即-c
,exit "$@ "
、sh
和42
(或您的命令)。最后两个参数将作为 argv[0](这是 shell 本身的名称)和第一个参数 argv[1] 传递给脚本,它将被替换为$@
。You are correct,
CMD
always passes its contents as new arguments to the entrypoint. You cannot insert it as part of an argument fromENTRYPOINT
.I'd also recommend Florin's solution, that is, having a custom entrypoint. However, if you really need to, you can still do it with shell only:
This will run
sh
with 4 arguments, being-c
,exit "$@"
,sh
and42
(or your command). The last two arguments are what will be passed to the script asargv[0]
(which is the name of the shell itself) andargv[1]
, the first argument, which will be substituted into$@
.