Powershell 入口点';s exec表单通过shell执行

Powershell 入口点';s exec表单通过shell执行,powershell,docker,dockerfile,docker-entrypoint,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 ["pow

我正在构建基于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形式时,命令将在没有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格式,这意味着数组元素中的
\
实例必须作为
\
转义

由于您的
ENTRYPOINT
指令因此不包含有效的JSON数组,Docker似乎回到了shell语法,因此将您的
ENTRYPOINT
参数传递给shell,在您的示例中,它是PowerShell,正如您的
SHELL
指令中所定义的那样,会导致SHELL命令中断。[1]

exec格式的语法正确的
入口点
,即有效的JSON,可以防止shell的参与,这在本例中是正确的方法
,因为您的命令只包含文字元素

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

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

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”]
被视为一个单独的参数-一个根据JSON规则转义的逐字字符串(将
\
字符加倍)-传递给shell,按照您的
SHELL
指令的定义。这意味着将该参数附加到
SHELL
数组的最后一个参数,前面加一个空格字符。你在日志中看到的就是证据。

你说得对!我没有想到Json中的反斜杠是问题所在。我甚至将Dockerfile的转义字符改为backtick thinking,这将传播到命令中,但它没有。很高兴听到它起作用了,@AmirKeibi。我的猜测是,可配置的转义字符仅适用于无引号的参数和行继续。
c:\spinner.exe service w3svc -t c:\iislog\W3SVC\u_extend1.log