【Docker】Dockerfile 之 SHELL
參考教程:https://docs.docker.com/engine/reference/builder/
環境
- virtual box 6.1
- centos 7.8
- docker 19.03
SHELL
SHELL ["executable", "parameters"]
The SHELL
instruction allows the default shell used for the shell form of commands to be overridden. The default shell on Linux is ["/bin/sh", "-c"]
, and on Windows is ["cmd", "/S", "/C"]
SHELL
instruction must be written in JSON form in a Dockerfile.
SHELL
指令允許覆蓋用於 shell 形式的命令的預設 shell。在 Linux 上,預設 shell 是 ["/bin/sh", "-c"]
,而在 Windows 上,預設 shell 是 ["cmd", "/S", "/C"]
。 SHELL
指令必須以 JSON 格式寫入 Dockerfile 中。
The SHELL
instruction is particularly useful on Windows where there are two commonly used and quite different native shells: cmd
powershell
, as well as alternate shells available including sh
.
SHELL
指令在 Windows 上特別有用,在 Windows 上有兩個常用且完全不同的本機shell:cmd
和 powershell
,以及可用的替代 shell,包括 sh
。
The SHELL
instruction can appear multiple times. Each SHELL
instruction overrides all previous SHELL
instructions, and affects all subsequent instructions. For example:
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
The following instructions can be affected by the SHELL
instruction when the shell form of them is used in a Dockerfile: RUN
, CMD
and ENTRYPOINT
.
當它們的 shell 形式在 Dockerfile 中使用時,以下指令可能會受到 SHELL
指令的影響:RUN
,CMD
和 ENTRYPOINT
。
The following example is a common pattern found on Windows which can be streamlined by using the SHELL
instruction:
以下示例是 Windows 上常見的模式,可以通過使用 SHELL
指令進行精簡:
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
The command invoked by docker will be:
docker 呼叫的命令將是:
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
This is inefficient for two reasons. First, there is an un-necessary cmd.exe command processor (aka shell) being invoked. Second, each RUN
instruction in the shell form requires an extra powershell -command
prefixing the command.
這效率低下有兩個原因。首先,有一個不必要的 cmd.exe 命令處理器(也稱為 shell)被呼叫。其次,shell 格式的每條 RUN
指令都需要在命令前面加上一個額外的 powershell -command
。
To make this more efficient, one of two mechanisms can be employed. One is to use the JSON form of the RUN command such as:
為了使其更有效,可以採用兩種機制之一。一種是使用 RUN 命令的 JSON 形式,例如:
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
While the JSON form is unambiguous and does not use the un-necessary cmd.exe, it does require more verbosity through double-quoting and escaping. The alternate mechanism is to use the SHELL
instruction and the shell form, making a more natural syntax for Windows users, especially when combined with the escape
parser directive:
儘管 JSON 形式是明確的,並且不使用不必要的 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'
Resulting in:
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
---> Running in 6fcdb6855ae2
---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
---> Running in d0eef8386e97
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/28/2016 11:26 AM Example
---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
---> Running in be6d8e63fe75
hello world
---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>
The SHELL
instruction could also be used to modify the way in which a shell operates. For example, using SHELL cmd /S /C /V:ON|OFF
on Windows, delayed environment variable expansion semantics could be modified.
SHELL
指令還可用於修改外殼的執行方式。例如,在 Windows 上使用 SHELL cmd /S /C /V:ON|OFF
,可以修改延遲的環境變數擴充套件語義。
The SHELL
instruction can also be used on Linux should an alternate shell be required such as zsh
, csh
, tcsh
and others.
如果需要備用外殼,例如 zsh
,csh
,tcsh
等,也可以在 Linux 上使用 SHELL
指令。
總結
介紹了 Dockerfile 中 SHELL 指令的用法和注意事項。