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

时间:2019-10-02 23:10:47

标签: powershell docker dockerfile docker-entrypoint

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

基本图像将外壳设置为Powershell

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

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

$ 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\"]"
            ],

我在这里误会了吗?

1 个答案:

答案 0 :(得分:1)

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

由于您的ENTRYPOINT指令因此不包含有效的JSON数组,因此Docker似乎退回到 shell 语法,因此传递了{{ 1}}是ENTRYPOINT指令中定义的Shell参数(在您的情况下为PowerShell),并且导致损坏的shell命令 < sup> [1]

语法正确的SHELL,格式为 exec -即有效的JSON-防止涉及shell,这是正确的方法,前提是您的命令仅包含 literal 元素。

因此,请尝试以下(ENTRYPOINT个实例以\转义):

\\

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

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

[1]发生的情况是,格式错误的c:\spinner.exe service w3svc -t c:\iislog\W3SVC\u_extend1.log 参数ENTRYPOINT被当作是参数,并传递给 shell {em>,如您的["c:\spinner.exe", "service", "w3svc", "-t", "c:\iislog\W3SVC\u_extend1.log"]指令所定义。这意味着将该参数附加到您的SHELL数组的最后一个参数之后,并以空格字符开头。将结果合并成一个命令行后,必须将SHELL转义为嵌入的"\字符,这说明了您在日志中看到的内容。 < / p>