在Ubuntu Docker中部署Shell脚本到ECS时遇文件不存在错误如何解决?
解决Docker部署ECS时
exec /pstart.sh: no such file or directory错误 问题背景
部署Docker镜像到ECS时触发错误:
exec /pstart.sh: no such file or directory
已确认文件存在,且尝试过以下操作仍未解决:
- 将脚本EOL从CRLF改为LF
- 替换shebang为
#!/bin/sh - 使用ENTRYPOINT替代CMD
- 用COPY替代ADD复制脚本
相关文件内容
Dockerfile
FROM public.ecr.aws/ubuntu/ubuntu:latest RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive \ apt install -yq \ curl \ jq \ openssh-server \ unzip \ vim \ dnsutils \ iputils-ping \ iputils-tracepath RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \ unzip awscliv2.zip && \ rm -f awscliv2.zip && \ ./aws/install ADD pstart.sh / RUN chmod +x /pstart.sh RUN echo PasswordAuthentication no >> /etc/ssh/sshd_config RUN echo Port 2224 >> /etc/ssh/sshd_config CMD ["/pstart.sh"]
pstart.sh
#!/bin/sh ssh-keygen -q -t rsa -N '' -f ~/.ssh/id_rsa <<<y >/dev/null 2>&1 cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys KEY_ID=$(aws kms list-aliases | jq -r '.Aliases | .[] | select(.AliasName=="alias/prod-smos-kms-key") | .TargetKeyId') aws ssm put-parameter --name smos-ssh-tunnel --value "$(cat ~/.ssh/id_rsa)" --type "SecureString" --overwrite --key-id "${KEY_ID}" service ssh start while (true); do sleep 5000 done
排查与解决步骤
1. 本地验证镜像内部状态
先在本地构建镜像并进入容器,确认脚本的实际运行状态:
# 构建镜像 docker build -t ecs-ssh-tunnel . # 进入容器交互终端 docker run --rm -it ecs-ssh-tunnel /bin/bash
在容器内执行以下检查:
- 确认文件存在且权限正确:
ls -l /pstart.sh,应显示类似-rwxr-xr-x 1 root root ... /pstart.sh的权限 - 验证shebang与解释器:
head -1 /pstart.sh # 应输出#!/bin/sh which /bin/sh # 应输出/bin/sh(Ubuntu默认链接到dash) - 手动运行脚本:
/pstart.sh,观察是否触发其他错误(如AWS权限问题,与当前"找不到文件"错误无关)
2. 检查脚本是否含BOM字符
如果脚本开头存在UTF-8 BOM(不可见字符),系统会将包含BOM的shebang行视为无效路径,导致"找不到文件"错误。用以下命令检查:
# 在容器内执行 cat -A /pstart.sh
若输出开头显示^#!/bin/sh(^代表BOM),需去除BOM:
- 本地编辑器中选择"无BOM的UTF-8"格式保存脚本
- 或用命令行处理:
sed -i '1s/^\xef\xbb\xbf//' pstart.sh
3. 解决架构不匹配问题
若构建环境为arm64(如M1/M2 Mac),而ECS使用x86_64实例,构建的arm64镜像在x86_64环境中可能出现兼容性问题。需指定平台构建x86_64镜像:
docker build --platform linux/amd64 -t ecs-ssh-tunnel . # 推送镜像到ECR时确保使用该平台版本
4. 切换CMD为shell形式
将Dockerfile中的CMD ["/pstart.sh"]改为CMD /pstart.sh,shell形式会让Docker自动通过/bin/sh -c /pstart.sh执行脚本,绕过exec形式的路径解析问题:
CMD /pstart.sh
5. 确认构建上下文与忽略规则
检查.dockerignore文件,确保未将pstart.sh排除在构建上下文之外;同时确认脚本文件位于构建命令执行的根目录下。
内容的提问来源于stack exchange,提问作者Ninad Kulkarni
相关产品推荐
相关产品推荐

