Dockerfile参考(18) – SHELL设置执行命令的shell

有运维或运维开发方面的需求,可以联系博主QQ 452336092或Email:admin#centos.bz(收费)

格式:

  1. SHELL ["executable", "parameters"]

SHELL指令可以覆盖命令的shell模式所使用的默认shell。Linux的默认shell是[“/bin/sh”, “-c”],Windows的是[“cmd”, “/S”, “/C”]。SHELL指令必须以JSON格式编写。
SHELL指令在有两个常用的且不太相同的本地shell:cmd和powershell,以及可选的sh的windows上特别有用。
SHELL指令可以出现多次。每个SHELL指令覆盖之前的SHELL指令设置的shell,并影响随便的指令。例如:

  1. FROM windowsservercore
  2.  
  3. # Executed as cmd /S /C echo default
  4. RUN echo default
  5.  
  6. # Executed as cmd /S /C powershell -command Write-Host default
  7. RUN powershell -command Write-Host default
  8.  
  9. # Executed as powershell -command Write-Host hello
  10. SHELL ["powershell", "-command"]
  11. RUN Write-Host hello
  12.  
  13. # Executed as cmd /S /C echo hello
  14. SHELL ["cmd", "/S"", "/C"]
  15. RUN echo hello

当RUN, CMD和ENTRYPOINT使用shell形式时,将使用SHELL指令设置的shell执行。
以下的示例是windows常见的模式,可以使用SHELL指令精简:

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

docker解析会是:

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

这个命令之所以低效有两个原因。首先,没有必须调用cmd.exe。第二,每个使用shell模式的RUN指令需要一个额外的powershell。
为了优化这个命令更有效率,有两个方法,其中之一使用RUN指令的JSON形式,如:

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

虽然没有调用了cmd.exe,不过需要对双引号进行转义,看起来比较冗长。另一种机制是使用SHELL指令和shell形式,使得windows用户可以使用更自然的语法,特别是与escape指令一起用时:

  1. # escape=`
  2.  
  3. FROM windowsservercore
  4. SHELL ["powershell","-command"]
  5. RUN New-Item -ItemType Directory C:\Example
  6. ADD Execute-MyCmdlet.ps1 c:\example\
  7. RUN c:\example\Execute-MyCmdlet -sample 'hello world'

构建结果为:

  1. PS E:\docker\build\shell> docker build -t shell .
  2. Sending build context to Docker daemon 3.584 kB
  3. Step 1 : FROM windowsservercore
  4.  ---> 5bc36a335344
  5. Step 2 : SHELL powershell -command
  6.  ---> Running in 87d7a64c9751
  7.  ---> 4327358436c1
  8. Removing intermediate container 87d7a64c9751
  9. Step 3 : RUN New-Item -ItemType Directory C:\Example
  10.  ---> Running in 3e6ba16b8df9
  11.  
  12.  
  13.     Directory: C:\
  14.  
  15.  
  16. Mode                LastWriteTime         Length Name
  17. ----                -------------         ------ ----
  18. d-----         6/2/2016   2:59 PM                Example
  19.  
  20.  
  21.  ---> 1f1dfdcec085
  22. Removing intermediate container 3e6ba16b8df9
  23. Step 4 : ADD Execute-MyCmdlet.ps1 c:\example\
  24.  ---> 6770b4c17f29
  25. Removing intermediate container b139e34291dc
  26. Step 5 : RUN c:\example\Execute-MyCmdlet -sample 'hello world'
  27.  ---> Running in abdcf50dfd1f
  28. Hello from Execute-MyCmdlet.ps1 - passed hello world
  29.  ---> ba0e25255fda
  30. Removing intermediate container abdcf50dfd1f
  31. Successfully built ba0e25255fda
  32. PS E:\docker\build\shell>

Docker 1.12开始添加了此SHELL功能。

转载请保留原文链接:Linux运维日志 » Dockerfile参考(18) – SHELL设置执行命令的shell

打赏

如果此文对你有所帮助,请随意打赏鼓励作者^_^

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址