Docker:可以将 cmdline 参数附加到 shell 内置命令参数中吗?

发布于 2025-01-11 02:22:15 字数 2913 浏览 7 评论 0原文

我想创建一个带有 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/ - 让我尝试了 ENTRYPOINTCMD 的组合:

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

我认为我对 ENTRYPOINTCMD 的失败实验可以通过这个实验来解释:

$ 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

春庭雪 2025-01-18 02:22:15

如果您定义了一个,则所有 docker run 参数都将传递到您的 entrypoint.sh

例如,在我的 Dockerfile 中,我有:

# prepare container
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]

在我的 entrypoint.sh 中

printf "Custom exit code '$*'\n"
exit "$@"

,然后使用 args 运行:

$ docker run verify 129
Custom exit code '129'
$ echo $?
129
$ _

All your docker run arguments are being passed to your entrypoint.sh if you have one defined.

For example in my Dockerfile I have:

# prepare container
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]

And in my entrypoint.sh

printf "Custom exit code '$*'\n"
exit "$@"

And then just run with args:

$ docker run verify 129
Custom exit code '129'
$ echo $?
129
$ _
半枫 2025-01-18 02:22:15

你是对的,CMD 总是将其内容作为新参数传递给入口点。您不能将其作为 ENTRYPOINT 参数的一部分插入。

我还推荐 Florin 的解决方案,即拥有一个自定义入口点。但是,如果您确实需要,您仍然可以仅使用 shell 来执行此操作:

from alpine

entrypoint ["/bin/sh", "-c", "exit \"$@\"", "sh"]

cmd ["42"]

这将使用 4 个参数运行 sh,即 -cexit "$@ "sh42 (或您的命令)。最后两个参数将作为 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 from ENTRYPOINT.

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:

from alpine

entrypoint ["/bin/sh", "-c", "exit \"$@\"", "sh"]

cmd ["42"]

This will run sh with 4 arguments, being -c, exit "$@", sh and 42 (or your command). The last two arguments are what will be passed to the script as argv[0] (which is the name of the shell itself) and argv[1], the first argument, which will be substituted into $@.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文