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

查看:24
本文介绍了通过 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:iislogW3SVCu_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"]"
            ],

我是不是误会了什么?

推荐答案

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

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

由于您的 ENTRYPOINT 指令因此不包含有效的 JSON 数组,看起来 Docker 正在回退到 shell 语法,因此通过您对 shell 的 ENTRYPOINT 参数,在您的情况下是 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 参与,这是正确的在这种情况下使用方法,因为您的命令仅包含 literal 元素.

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:iislogW3SVCu_extend1.log


[1] 发生的情况是格式错误的 ENTRYPOINT 参数、[c:spinner.exe"、service"、w3svc"、";-t"、c:iislogW3SVCu_extend1.log"] 被视为 single 参数 - 逐字字符串根据 JSON 规则进行转义( 字符加倍.) - 传递给 shell,如您的 SHELL 指令所定义.这意味着将该参数附加到 SHELL 数组的最后一个参数,前面有一个空格字符.你在日志中看到的就是证据.


[1] What happens is that the malformed ENTRYPOINT argument, ["c:spinner.exe", "service", "w3svc", "-t", "c:iislogW3SVCu_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天全站免登陆