如何在Alpine Docker容器中运行Bash脚本?

如何在Alpine Docker容器中运行Bash脚本?,docker,dockerfile,alpine,Docker,Dockerfile,Alpine,我有一个只包含两个文件的目录,Dockerfile和sayhello.sh: . ├── Dockerfile └── sayhello.sh Dockerfile读取 FROM alpine COPY sayhello.sh sayhello.sh CMD ["sayhello.sh"] 而sayhello.sh只包含 echo hello Dockerfile成功生成: kurtpeek@Sophiemaries-MacBook-Pro ~/d/s/trybash&

我有一个只包含两个文件的目录,
Dockerfile
sayhello.sh

.
├── Dockerfile
└── sayhello.sh
Dockerfile
读取

FROM alpine
COPY sayhello.sh sayhello.sh
CMD ["sayhello.sh"]
sayhello.sh
只包含

echo hello
Dockerfile
成功生成:

kurtpeek@Sophiemaries-MacBook-Pro ~/d/s/trybash> docker build --tag trybash .
Sending build context to Docker daemon 3.072 kB
Step 1/3 : FROM alpine
 ---> 665ffb03bfae
Step 2/3 : COPY sayhello.sh sayhello.sh
 ---> Using cache
 ---> fe41f2497715
Step 3/3 : CMD sayhello.sh
 ---> Using cache
 ---> dfcc26c78541
Successfully built dfcc26c78541
但是,如果我尝试
运行
它,我会在$PATH中找到一个
可执行文件
错误:

kurtpeek@Sophiemaries-MacBook-Pro ~/d/s/trybash> docker run trybash
container_linux.go:247: starting container process caused "exec: \"sayhello.sh\": executable file not found in $PATH"
docker: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "exec: \"sayhello.sh\": executable file not found in $PATH".
ERRO[0001] error getting events from daemon: net/http: request canceled
这是什么原因造成的?我记得在基于
debian:jessie
的图像中以类似的方式运行脚本。因此,它可能是特定于Alpine的?

Alpine作为默认shell而不是
bash

所以你可以

  • 将/bin/bash定义为sayhello.sh的第一行,这样文件sayhello.sh将以bin/sh开头

    #!/bin/sh
    
  • 在您的Alpine映像中安装Bash,正如您所期待的那样,Dockerfile中有这样一行代码:

    RUN apk add --no-cache --upgrade bash
    

  • 通过使用
    CMD
    ,Docker正在
    路径中搜索
    sayhello.sh
    文件,但您将其复制到了
    /
    路径中不存在的

    因此,请使用要执行的脚本的绝对路径:

    CMD ["/sayhello.sh"]
    

    顺便说一句,正如@user2915097所说的,如果您的脚本在shebang中使用Bash,请注意Alpine在默认情况下没有Bash。

    请记住为所有脚本授予执行权限

    FROM alpine
    COPY sayhello.sh /sayhello.sh
    RUN chmod +x /sayhello.sh
    CMD ["/sayhello.sh"]
    
    完全正确,工作正常

    还有另一种方法。您可以在基于Alpine的Docker容器中运行Bash脚本

    您需要更改CMD,如下所示:

    CMD ["sh", "sayhello.sh"]
    

    这也行。

    如果docker文件已经有权限,那么授予执行权限在docker文件中是不需要的。请不要冒昧地问你一个问题,因为当我以这种方式终止docker文件时,我已经用
    docker compose-d
    运行了它,我无法访问
    bash
    ,而对于
    php之类的其他容器,nginx
    CMD
    结尾,我可以访问
    bash
    @jcarlosweb,因为Alpine没有提供bash,只有ash可以使用,尽管bash脚本与sh脚本不100%兼容。我相信sh代表shell,而Bash代表Bourne代表shell。为了让未来的访问者知道他们真的是不同的shell。将Dockerfile中的
    CMD[“sayhello.sh”]
    更改为
    CMD[“/sayhello.sh”]
    为我解决了这个问题,而无需安装Bash。