容器中start.sh存在却提示找不到?保留bash头的Dockerfile修复方案
问题:Alpine容器执行start.sh提示"exec ./start.sh: no such file or directory",但文件实际存在
环境与配置
Dockerfile(多阶段构建)
FROM golang:1.19 AS builder WORKDIR /app COPY . . RUN CGO_ENABLED=0 go build -v -o "hello-bin" FROM alpine COPY --from=builder /app/hello-bin /app/hello-bin COPY --from=builder /app/start.sh /app/start.sh WORKDIR /app ENTRYPOINT [ "./start.sh" ]
docker-compose.yaml
version: "3" services: hello: restart: always build: context: . dockerfile: Dockerfile
本地目录结构
. ├── Dockerfile ├── docker-compose.yaml ├── go.mod ├── hello ├── init.go └── start.sh
start.sh内容
#!/bin/bash _main() { echo "start" } _main "$@"
异常现象
- 将ENTRYPOINT改为
CMD [ "ls", "-l" ],能看到start.sh确实存在且有执行权限 - 改为
ENTRYPOINT [ './hello-bin' ]时,Go二进制文件可正常运行 - 仅执行
start.sh时提示exec ./start.sh: no such file or directory - 将
start.sh的shebang改为#!/bin/sh后可正常运行
底层原因分析
- Alpine镜像默认无bash:Alpine基于musl libc,默认只预装了轻量级的
ash(属于busybox套件),没有安装bash。当脚本头部的shebang指定#!/bin/bash时,系统找不到对应的解释器,就会抛出"文件不存在"的错误——这个错误不是指脚本本身找不到,而是指脚本指定的解释器/bin/bash不存在。 - 错误信息的误导性:容器执行脚本时,内核会尝试启动shebang指定的解释器,若找不到就会返回类似"exec ...: no such file or directory"的提示,容易让用户误以为是脚本本身缺失。
保留bash头的解决方法
要在Alpine容器中使用bash作为脚本解释器,只需在Dockerfile中安装bash即可:
修改后的Dockerfile
FROM golang:1.19 AS builder WORKDIR /app COPY . . RUN CGO_ENABLED=0 go build -v -o "hello-bin" FROM alpine # 通过apk安装bash,--no-cache避免缓存包索引以减小镜像体积 RUN apk add --no-cache bash COPY --from=builder /app/hello-bin /app/hello-bin COPY --from=builder /app/start.sh /app/start.sh WORKDIR /app ENTRYPOINT [ "./start.sh" ]
安装完成后,/bin/bash路径会存在,脚本的#!/bin/bash头即可正常生效。
内容的提问来源于stack exchange,提问作者IsaIkari
相关产品推荐
相关产品推荐

