dockerfile深入学习之SHELL

SHELL指令:允许覆盖用于shell命令形式的默认shell

语法形式:SHELL ["executable", "parameters"]

  • linux默认shell表示为["/bin/sh", "-c"]
  • Windows 下表示为 ["cmd", "/S", "/C"]

SHELL指令可以在一个Dockerfile中出现多次、每个SHELL都会覆盖之前所有的shell并影响后续指令、如下:

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello

如果在Dockerfile中使用SHELL指令,则会影响以下指令:RUN,CMD和ENTRYPOINT。

shell具体作用见实例:

首先看一个原始模式:

...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...

在docker中命令调用如下:

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

通过观察不难发现、以上方式效率不高

首先,它调用了一个不必要的cmd.exe命令处理器(又名shell)。 其次,shell格式中的每条RUN指令都需要在命令前加上一个额外的powershell命令。

为提高效率、可以通过RUN指令的JSON数组形式调用、如下:

...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...

以上方式不再需要不必要的cmd.exe处理器、但我们可以看到、通过JSON数组的方式使得一行中指令内容过于冗余、因此我们可以使用shell指令和escape parser指令结合的方式。如下:

# escape=`

FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'

由此、通过SHELL指令、我们即提高了执行效率、也不会出现JSON冗长的问题

另外:SHELL指令也可以用来修改shell的运行方式。 例如,在Windows上使用SHELL cmd / S / C / V:ON | OFF,可以修改延迟的环境变量扩展语义。

如果需要备用shell,如zsh,csh,tcsh等,SHELL指令也可以在Linux上使用。

posted on 2018-01-19 15:32  残天  阅读(270)  评论(0)    收藏  举报

导航