Dockerfile文件SHELL指令可以覆蓋命令的shell模式所使用的默認shell。Linux的默認shell是[“/bin/sh”, “-c”],Windows的是[“cmd”, “/S”, “/C”]。SHELL指令必須以JSON格式編寫。
語法格式
SHELL ["executable", "parameters"]
該SHELL指令在Windows上特別有用,在Windows上有兩個常用且完全不同的本機shell:cmd和powershell,以及可用的替代shell包括sh。
該SHELL說明可以出現多次。每個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
當RUN, CMD和ENTRYPOINT使用shell形式時,將使用SHELL指令設置的shell執行。
以下的示例是windows常見的模式,可以使用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 -command
為了使其更有效,可以采用兩種機制之一。一種是使用RUN命令的JSON形式,例如:
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
雖然沒有調用了cmd.exe,不過需要對雙引號進行轉義,看起來比較冗長。另一種機制是使用SHELL指令和shell形式,使得windows用戶可以使用更自然的語法,特別是與escape指令一起用時:
# 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'







