Entrypoint的exec形式通过shell执行

2023-12-04

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

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:

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

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

$ 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 执行的:

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

我在这里误解了什么吗?


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

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]

语法正确的ENTRYPOINT in exec格式 - 即有效的 JSON -prevents涉及 shell,这是本例中的正确方法,假设您的命令包含literal仅元素。

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

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

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

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

[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.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Entrypoint的exec形式通过shell执行 的相关文章

随机推荐