本质是运行时无法定位或执行文件,根源在路径、权限、编码、解释器、挂载五环节:先用docker run --rm -it <image> ls -l /app/run.sh验证存在性;若不存在则检查Dockerfile的COPY路径与上下文;若存在但权限异常或显示^M,需修复CRLF换行、确保shebang解释器已安装并赋执行权限;挂载时注意-v会覆盖镜像内文件。
容器启动时报“找不到文件”,比如 /bin/sh: 1: /app/run.sh: not found 或 no such file or directory,本质不是“文件真丢了”,而是容器运行时无法按预期定位或执行它。问题根源集中在路径、权限、编码、解释器和挂载这五个关键环节。
确认文件是否真的在镜像里
别猜,先验证。用以下命令检查镜像中是否存在目标文件:
-
docker run --rm -it <image-name> ls -l /app/run.sh(替换为你的实际路径) - 如果报错“no such file”,说明构建阶段就没复制进去——检查 Dockerfile 中
COPY或ADD指令的源路径是否正确、文件是否在构建上下文目录内 - 若文件存在但显示为
?????????? ? ? ? ? ? /app/run.sh,可能是挂载覆盖或权限异常,需进一步排查
检查脚本换行符与解释器兼容性
Windows 编辑的脚本带 CRLF(\r\n),Linux 容器只认 LF(\n)。shebang 行末的 \r 会让系统误认为解释器路径是 /bin/bash\r,从而报 “not found”。
- 进容器执行:
cat -A /app/run.sh | head -n1,若看到#!/bin/bash^M$就是 CRLF 问题 - 修复方式:本地用
dos2unix run.sh转换,或在 Dockerfile 中加一步:RUN apt-get update && apt-get install -y dos2unix && dos2unix /app/run.sh - 同时确认 shebang 指向的解释器存在,例如 Alpine 镜像没有
/bin/bash,应改用#!/bin/sh或安装 bash
验证执行权限与用户上下文
Linux 下脚本必须有 x 权限才能执行;且运行用户需对文件和父目录都有读+执行(r-x)权限。
- 构建时显式赋权:
RUN chmod +x /app/run.sh(推荐放在 COPY 后) - 检查容器内权限:
docker run --rm -it <image> ls -l /app/,确认输出类似-rwxr-xr-x 1 root root ... run.sh - 若使用非 root 用户启动(如
USER appuser),确保该用户对/app目录有访问权,必要时RUN chown -R appuser:appuser /app
排查挂载与路径覆盖行为
运行时通过 -v 挂载宿主机目录,会**完全覆盖**镜像中同路径内容。若挂载点是 /app,而宿主机该目录下没有 run.sh,容器就真的“找不到”。
- 检查启动命令是否含
-v,例如docker run -v $(pwd):/app ...—— 这会把当前目录覆盖进/app,原镜像文件被隐藏 - 避免整目录挂载,改用精确文件挂载:
-v $(pwd)/run.sh:/app/run.sh:ro - 若必须挂载目录,确保宿主机对应路径下包含所有必需文件,或改用命名 volume 管理配置类文件


















