我正在尝试运行一个docker映像,该映像执行一个bash脚本并将运行时参数传递给该bash脚本。我发现当我使用推荐的ENTRYPOINT ["/bin/bash", "-c", ". foo.sh"]
入口点构建映像时,脚本中没有附加到docker run
命令后面的第一个参数,但是当我使用{{ 1}},确实如此。
Shell脚本的玩具版本如下:
ENTRYPOINT ["bash", "foo.sh"]
因此,基本上,脚本需要最多4个命令行参数,每个参数都具有默认值。
我尝试过的原始Dockerfile如下所示:
#!/bin/bash
echo you got "$#" args
ARG1=${1:-foo}
ARG2=${2:-bar}
ARG3=${3:-1}
ARG4=${4:-$(date)}
echo "$ARG1"
echo "$ARG2"
echo "$ARG3"
echo "$ARG4"
并且基于我发现的许多资源,这些资源介绍了如何使用ENTRYPOINT recommended by docker的 exec 形式正确执行shell脚本。
使用FROM ubuntu
COPY foo.sh foo.sh
ENTRYPOINT ["/bin/bash", "-c", ". foo.sh"]
构建此图像后,我使用docker build -t foo .
运行它,并得到以下输出:
docker run -it foo first second third fourth
因此很显然,附加到you got 3 args
second
third
fourth
Tue Jul 2 13:14:52 UTC 2019
命令的第一个参数沿行放置在某处,shell命令提取的唯一参数是第二,第三和第四。
我花了很长时间尝试诊断这个问题,但到目前为止还没有弄清楚为什么会这样。在发现将入口点更改为简单的docker run
会产生理想的结果之后,我想出的最好办法是一种变通的解决方法。
我想知道以下几点:1.为什么原始入口点会删除第一个运行时参数? 2.为什么第二个入口点的工作方式与第一个入口点不同?
答案 0 :(得分:4)
运行bash -c 'something' foo bar baz
时,“ foo”成为第零个参数(即$0
)
也许您需要在其中插入一个虚拟参数
ENTRYPOINT ["/bin/bash", "-c", ". foo.sh", "bash"]
这在bash手册页的-c
选项的说明中得到了记录。
答案 1 :(得分:3)
一个Docker容器运行一个进程,具体情况由ENTRYPOINT设置指定;当该进程退出时,容器退出。这意味着您不需要更新周围的Shell环境,因此不需要使用内置的.
运行脚本;而且,当您只运行一个简单的命令时,也无需将命令包装在sh -c
包装器中。
这会产生类似Dockerfile
FROM ubuntu
COPY foo.sh foo.sh
RUN chmod +x foo.sh # if it’s not executable already
ENTRYPOINT ["./foo.sh"]
这也避免了sh -c
使用@GlennJackman的答案中提到的第一个参数的问题。