通过 shell 执行的 Entrypoint 的 exec 形式 [英] Entrypoint's exec form executed through shell

查看:107
本文介绍了通过 shell 执行的 Entrypoint 的 exec 形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个基于 Windows 的 docker 镜像:

I'm building a Windows based docker image:

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019

# omitted for brevity

ENTRYPOINT ["c:\spinner.exe", "service", "w3svc", "-t", "c:\iislog\W3SVC\u_extend1.log"]

基础镜像将 shell 设置为 Powershell:

The base image sets the shell to Powershell:

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

我的理解是,当使用 ENTRYPOINT 指令的 exec 形式时,该命令将在没有 shell 的情况下执行.但是,当我创建容器时,它失败并显示以下错误:

My understanding was that when the exec form of the ENTRYPOINT instruction is used, the command will be executed without a shell. However, when I create the container, it fails with this error:

$ docker run -d -p 80:80 --isolation process --name pht site:local


$ docker logs pht

At line:1 char:77
+ ... ference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; [C:\\spin ...
+                                                                  ~
Missing ] at end of attribute or type literal.
At line:1 char:78
+ ... '; $ProgressPreference = 'SilentlyContinue'; [C:\\spinner.exe, servic ...
+                                                    ~~~~~~~~~~~~~~
Unexpected token ':\\spinner.exe' in expression or statement.
At line:1 char:92
+ ... ; $ProgressPreference = 'SilentlyContinue'; [C:\\spinner.exe, service ...
+                                                                 ~
Missing argument in parameter list.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordEx
   ception
    + FullyQualifiedErrorId : EndSquareBracketExpectedAtEndOfAttribute

当我检查停止的容器时,我看到执行的命令是通过 shell 执行的:

And when I inspect the stopped container, I see the executed command was through shell:

 "Entrypoint": [
                "powershell -Command $ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; [\"c:\\spinner.exe\", \"service\", \"w3svc\", \"-t\", \"c:\\iislog\\W3SVC\\u_extend1.log\"]"
            ],

我在这里误解了什么吗?

Am I misunderstanding something here?

推荐答案

exec 语法需要 JSON 格式,这意味着必须对数组元素中的 \ 实例进行转义作为 \\.

The exec syntax requires JSON format, which means that \ instances in the array elements must be escaped as \\.

由于您的 ENTRYPOINT 指令不包含有效的 JSON 数组,看起来 Docker 正在回退到 shell 语法,因此通过你的 ENTRYPOINT 参数给 shell,在你的例子中是 PowerShell,在你的 SHELL 指令中定义 - 这导致一个 损坏的 shell 命令.[1]

Since your ENTRYPOINT instruction therefore does not contain a valid JSON array, it looks like Docker is falling back to shell syntax and therefore passes your ENTRYPOINT argument to the shell, which in your case is PowerShell, as defined in your SHELL instruction - and that results in a broken shell command.[1]

exec 格式的语法正确的 ENTRYPOINT - 即有效的 JSON - 防止 shell 的参与,这是正确的在这种情况下的方法,因为您的命令仅包含文字元素.

A syntactically correct ENTRYPOINT in exec format - i.e., valid JSON - prevents involvement of a shell, which is the correct approach in this case, given that your command contains literal elements only.

因此,请尝试以下操作(\ 实例转义为 \\):

Therefore, try the following (\ instances escaped as \\):

ENTRYPOINT ["c:\\spinner.exe", "service", "w3svc", "-t", "c:\\iislog\\W3SVC\\u_extend1.log"]

这样,Docker 应该最终在容器中执行以下命令行:

That way, Docker should end up executing the following command line in the container:

c:\spinner.exe service w3svc -t c:\iislog\W3SVC\u_extend1.log


[1] 会发生什么是格式错误的 ENTRYPOINT 参数,[c:\spinner.exe", service", w3svc", ";-t", c:\iislog\W3SVC\u_extend1.log"],被视为一个单个参数 - 一个逐字串根据 JSON 规则进行转义(\ 字符的两倍.) - 传递给 shell,由您的 SHELL 指令定义.这意味着将该参数附加到 SHELL 数组的最后一个参数,并以空格字符开头.你在日志中看到的就是证据.


[1] What happens is that the malformed ENTRYPOINT argument, ["c:\spinner.exe", "service", "w3svc", "-t", "c:\iislog\W3SVC\u_extend1.log"], is taken to be a single argument - a verbatim string to be escaped based on JSON rules (doubling of \ chars.) - to be passed to the shell, as defined by your SHELL instruction. This means appending that argument to the last argument of your SHELL array, preceded by a space character. What you saw in the logs is evidence of that.

这篇关于通过 shell 执行的 Entrypoint 的 exec 形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆