SHELL指令用于显式设置Docker构建阶段RUN等shell形式指令的默认解释器,需用JSON数组格式如["bash","-c"],仅影响后续shell形式指令且可被多次覆盖。
shell 指令用于显式设置后续 run(以及 cmd、entrypoint 的 shell 形式)所使用的默认 shell 及其参数,它不改变系统底层的 shell,而是覆盖 docker 构建阶段的执行解释器。
什么时候需要改 SHELL?
常见于以下场景:
- 基础镜像不含
/bin/sh(如某些 Alpine 镜像默认只有/bin/ash,或 Windows Nano Server 用powershell) - 想统一使用
bash获取更丰富的语法支持(如数组、条件扩展) - 避免因 shell 差异导致的命令行为不一致(例如
source、[[ ]]在sh中不可用) - 在 Windows 多架构构建中切换 PowerShell 或 cmd
基本语法与写法
SHELL 必须使用 JSON 数组格式,且每个元素必须是字符串(双引号):
SHELL ["bash", "-c"]
之后所有未显式指定为 exec 形式的 RUN 指令,都会通过 bash -c "..." 执行。
也可以设为其他 shell:
SHELL ["powershell", "-Command"] # Windows 镜像常用<br>SHELL ["sh", "-euxo", "pipefail"] # 增强 sh 的错误处理和调试能力
注意事项
-
SHELL只影响 后续 的 shell 形式指令,不影响已写好的 exec 形式(如RUN ["ls"]) - 它不会修改容器运行时的默认 shell;
CMD或docker run启动的交互式终端仍取决于镜像中/bin/sh的存在或用户配置 - 多次声明
SHELL会覆盖前值,最后生效的是最后一次定义 - Windows 路径需注意反斜杠转义:正确写法是
SHELL ["powershell", "-Command"],而不是含单斜杠的错误形式
实际效果示例
默认情况下:
RUN echo $HOME
等价于 /bin/sh -c "echo $HOME",能展开变量。
若先写:
SHELL ["bash", "-c"]<br>RUN echo "当前 shell: $(basename $SHELL)"
则输出 当前 shell: bash;而如果没改 SHELL,可能输出 sh。
若想让某条 RUN 临时绕过 SHELL 设置,直接用 exec 格式即可:
RUN ["/bin/sh", "-c", "echo fallback to sh"]


















