繁体   English   中英

通过 shell 执行的入口点的 exec 表单

[英]Entrypoint's exec form executed through shell

我正在构建一个基于 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';"]

我的理解是,当使用ENTRYPOINT指令的 exec 形式时,该命令将在没有 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\"]"
            ],

我在这里误解了什么吗?

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在损坏的 shell 命令中。 [1]

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

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

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] 发生的情况是格式错误的ENTRYPOINT参数["c:\spinner.exe", "service", "w3svc", "-t", "c:\iislog\W3SVC\u_extend1.log"]是被视为单个参数 - 根据 JSON 规则( \字符加倍)转义的逐字字符串- 传递给shell ,如SHELL指令所定义的那样。 这意味着将该参数附加到SHELL数组的最后一个参数,前面有一个空格字符。 你在日志中看到的就是证据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM