You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dockerfile RUN命令跨机器执行异常及脚本解释器疑问

Docker构建镜像报错问题解答

问题背景

Dockerfile配置片段:

FROM nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu20.04
...
RUN ./my_script.sh

脚本my_script.sh首行声明为#!/bin/bash。同事在Linux Ubuntu 22.04环境下可正常构建镜像,但在Windows 11的WSL2(Ubuntu 22.04)环境下执行docker compose build时,出现如下错误:

ERROR [application 10/11] RUN ./my_script.sh 
0.426 /bin/sh: 1: ./my_script.sh: not found

疑问解答

1. 容器操作系统一致,RUN命令在容器内执行,为何不同机器表现不同?

核心原因是Windows与Linux的换行符差异:

  • Windows系统默认使用CRLF(\r\n)作为换行符,Linux则使用LF(\n)。如果你的脚本是在Windows环境下编辑的,换行符会是CRLF,当通过WSL2挂载到Docker构建上下文并复制到容器后,脚本首行的#!/bin/bash会被解析为#!/bin/bash\r,系统找不到名为/bin/bash\r的解释器,从而抛出"not found"错误。
  • 同事直接在Linux环境下编辑脚本,换行符为LF,复制到容器后解释器路径正常,因此可以顺利执行。
  • 另外需排除文件权限问题:若脚本无执行权限,报错会是"Permission denied",与当前报错不符,因此换行符问题是主要诱因。

2. 脚本已声明/bin/bash,为何错误提示使用/bin/sh?

  • Docker的RUN命令默认使用/bin/sh作为执行shell。当脚本的解释器路径因换行符问题失效时,系统会 fallback 到默认的/bin/sh尝试执行脚本,但此时脚本的有效解释器路径不存在,所以/bin/sh会抛出"not found"的错误提示(该信息有一定误导性,实际是找不到有效解释器导致脚本无法执行)。
  • 可以通过两种方式规避:一是显式指定用bash执行脚本,将RUN ./my_script.sh改为RUN bash ./my_script.sh;二是在Dockerfile开头添加SHELL ["/bin/bash", "-c"],让后续所有RUN命令默认使用bash执行。

解决方法

  • 转换脚本换行符:在编辑器(如VS Code)右下角将换行符切换为LF,或在WSL2终端执行dos2unix my_script.sh命令完成转换。
  • 确保脚本可执行:在WSL2终端执行chmod +x my_script.sh,或在Dockerfile中RUN ./my_script.sh之前添加RUN chmod +x ./my_script.sh。

内容的提问来源于stack exchange,提问作者Jakub Małecki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 07:03:38